fix: USV3 encoding/decoding after rebase
- Also do some renamings and comment improvements: transfer method -> type - Remove integration tests since we no longer support direct calls to USV3 executor, even for testing.
This commit is contained in:
committed by
Diana Carvalho
parent
7e98145ad7
commit
f3c4128eda
@@ -5,7 +5,7 @@ import "@interfaces/IExecutor.sol";
|
|||||||
import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
|
import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
|
||||||
import "@permit2/src/interfaces/IAllowanceTransfer.sol";
|
import "@permit2/src/interfaces/IAllowanceTransfer.sol";
|
||||||
|
|
||||||
error TokenTransfer__InvalidPermit2();
|
error TokenTransfer__AddressZero();
|
||||||
|
|
||||||
contract TokenTransfer {
|
contract TokenTransfer {
|
||||||
using SafeERC20 for IERC20;
|
using SafeERC20 for IERC20;
|
||||||
@@ -25,7 +25,7 @@ contract TokenTransfer {
|
|||||||
|
|
||||||
constructor(address _permit2) {
|
constructor(address _permit2) {
|
||||||
if (_permit2 == address(0)) {
|
if (_permit2 == address(0)) {
|
||||||
revert TokenTransfer__InvalidPermit2();
|
revert TokenTransfer__AddressZero();
|
||||||
}
|
}
|
||||||
permit2 = IAllowanceTransfer(_permit2);
|
permit2 = IAllowanceTransfer(_permit2);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ error UniswapV3Executor__InvalidDataLength();
|
|||||||
error UniswapV3Executor__InvalidFactory();
|
error UniswapV3Executor__InvalidFactory();
|
||||||
error UniswapV3Executor__InvalidTarget();
|
error UniswapV3Executor__InvalidTarget();
|
||||||
error UniswapV3Executor__InvalidInitCode();
|
error UniswapV3Executor__InvalidInitCode();
|
||||||
|
error UniswapV3Executor__InvalidTransferType(uint8 transferType);
|
||||||
|
|
||||||
contract UniswapV3Executor is IExecutor, ICallback, TokenTransfer {
|
contract UniswapV3Executor is IExecutor, ICallback, TokenTransfer {
|
||||||
using SafeERC20 for IERC20;
|
using SafeERC20 for IERC20;
|
||||||
@@ -97,12 +98,13 @@ contract UniswapV3Executor is IExecutor, ICallback, TokenTransfer {
|
|||||||
|
|
||||||
address tokenIn = address(bytes20(msgData[132:152]));
|
address tokenIn = address(bytes20(msgData[132:152]));
|
||||||
|
|
||||||
require(
|
// Transfer type does not exist
|
||||||
uint8(msgData[171]) <= uint8(TransferType.NONE),
|
if (uint8(msgData[175]) > uint8(TransferType.NONE)) {
|
||||||
"InvalidTransferMethod"
|
revert UniswapV3Executor__InvalidTransferType(uint8(msgData[175]));
|
||||||
);
|
}
|
||||||
TransferType transferType = TransferType(uint8(msgData[171]));
|
|
||||||
address sender = address(bytes20(msgData[172:192]));
|
TransferType transferType = TransferType(uint8(msgData[175]));
|
||||||
|
address sender = address(bytes20(msgData[176:196]));
|
||||||
|
|
||||||
verifyCallback(msgData[132:]);
|
verifyCallback(msgData[132:]);
|
||||||
|
|
||||||
@@ -168,7 +170,7 @@ contract UniswapV3Executor is IExecutor, ICallback, TokenTransfer {
|
|||||||
TransferType transferType
|
TransferType transferType
|
||||||
) internal view returns (bytes memory) {
|
) internal view returns (bytes memory) {
|
||||||
return abi.encodePacked(
|
return abi.encodePacked(
|
||||||
tokenIn, tokenOut, fee, uint8(transferType), msg.sender, self
|
tokenIn, tokenOut, fee, uint8(transferType), msg.sender
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ contract UniswapV3ExecutorExposed is UniswapV3Executor {
|
|||||||
address receiver,
|
address receiver,
|
||||||
address target,
|
address target,
|
||||||
bool zeroForOne,
|
bool zeroForOne,
|
||||||
TransferType method
|
TransferType transferType
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
return _decodeData(data);
|
return _decodeData(data);
|
||||||
@@ -81,7 +81,7 @@ contract UniswapV3ExecutorTest is Test, Constants, Permit2TestHelper {
|
|||||||
address receiver,
|
address receiver,
|
||||||
address target,
|
address target,
|
||||||
bool zeroForOne,
|
bool zeroForOne,
|
||||||
TokenTransfer.TransferType method
|
TokenTransfer.TransferType transferType
|
||||||
) = uniswapV3Exposed.decodeData(data);
|
) = uniswapV3Exposed.decodeData(data);
|
||||||
|
|
||||||
assertEq(tokenIn, WETH_ADDR);
|
assertEq(tokenIn, WETH_ADDR);
|
||||||
@@ -90,7 +90,9 @@ contract UniswapV3ExecutorTest is Test, Constants, Permit2TestHelper {
|
|||||||
assertEq(receiver, address(2));
|
assertEq(receiver, address(2));
|
||||||
assertEq(target, address(3));
|
assertEq(target, address(3));
|
||||||
assertEq(zeroForOne, false);
|
assertEq(zeroForOne, false);
|
||||||
assertEq(uint8(method), uint8(TokenTransfer.TransferType.TRANSFER));
|
assertEq(
|
||||||
|
uint8(transferType), uint8(TokenTransfer.TransferType.TRANSFER)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function testDecodeParamsInvalidDataLength() public {
|
function testDecodeParamsInvalidDataLength() public {
|
||||||
@@ -142,88 +144,6 @@ contract UniswapV3ExecutorTest is Test, Constants, Permit2TestHelper {
|
|||||||
assertEq(finalPoolReserve - initialPoolReserve, amountOwed);
|
assertEq(finalPoolReserve - initialPoolReserve, amountOwed);
|
||||||
}
|
}
|
||||||
|
|
||||||
function testSwapWithTransfer() public {
|
|
||||||
uint256 amountIn = 10 ** 18;
|
|
||||||
deal(WETH_ADDR, address(uniswapV3Exposed), amountIn);
|
|
||||||
|
|
||||||
uint256 expAmountOut = 1205_128428842122129186; //Swap 1 WETH for 1205.12 DAI
|
|
||||||
bool zeroForOne = false;
|
|
||||||
|
|
||||||
bytes memory data = encodeUniswapV3Swap(
|
|
||||||
WETH_ADDR,
|
|
||||||
DAI_ADDR,
|
|
||||||
address(this),
|
|
||||||
DAI_WETH_USV3,
|
|
||||||
zeroForOne,
|
|
||||||
TokenTransfer.TransferType.TRANSFER
|
|
||||||
);
|
|
||||||
|
|
||||||
uint256 amountOut = uniswapV3Exposed.swap(amountIn, data);
|
|
||||||
|
|
||||||
assertGe(amountOut, expAmountOut);
|
|
||||||
assertEq(IERC20(WETH_ADDR).balanceOf(address(uniswapV3Exposed)), 0);
|
|
||||||
assertGe(IERC20(DAI_ADDR).balanceOf(address(this)), expAmountOut);
|
|
||||||
}
|
|
||||||
|
|
||||||
function testSwapWithTransferFrom() public {
|
|
||||||
uint256 amountIn = 10 ** 18;
|
|
||||||
deal(WETH_ADDR, address(this), amountIn);
|
|
||||||
IERC20(WETH_ADDR).approve(address(uniswapV3Exposed), amountIn);
|
|
||||||
|
|
||||||
uint256 expAmountOut = 1205_128428842122129186; //Swap 1 WETH for 1205.12 DAI
|
|
||||||
bool zeroForOne = false;
|
|
||||||
|
|
||||||
bytes memory data = encodeUniswapV3Swap(
|
|
||||||
WETH_ADDR,
|
|
||||||
DAI_ADDR,
|
|
||||||
address(this),
|
|
||||||
DAI_WETH_USV3,
|
|
||||||
zeroForOne,
|
|
||||||
TokenTransfer.TransferType.TRANSFERFROM
|
|
||||||
);
|
|
||||||
|
|
||||||
uint256 amountOut = uniswapV3Exposed.swap(amountIn, data);
|
|
||||||
|
|
||||||
assertGe(amountOut, expAmountOut);
|
|
||||||
assertEq(IERC20(WETH_ADDR).balanceOf(address(uniswapV3Exposed)), 0);
|
|
||||||
assertGe(IERC20(DAI_ADDR).balanceOf(address(this)), expAmountOut);
|
|
||||||
}
|
|
||||||
|
|
||||||
function testSwapWithPermit2TransferFrom() public {
|
|
||||||
uint256 amountIn = 10 ** 18;
|
|
||||||
|
|
||||||
uint256 expAmountOut = 1205_128428842122129186; //Swap 1 WETH for 1205.12 DAI
|
|
||||||
bool zeroForOne = false;
|
|
||||||
|
|
||||||
bytes memory data = encodeUniswapV3Swap(
|
|
||||||
WETH_ADDR,
|
|
||||||
DAI_ADDR,
|
|
||||||
address(this),
|
|
||||||
DAI_WETH_USV3,
|
|
||||||
zeroForOne,
|
|
||||||
TokenTransfer.TransferType.TRANSFERPERMIT2
|
|
||||||
);
|
|
||||||
|
|
||||||
deal(WETH_ADDR, ALICE, amountIn);
|
|
||||||
vm.startPrank(ALICE);
|
|
||||||
(
|
|
||||||
IAllowanceTransfer.PermitSingle memory permitSingle,
|
|
||||||
bytes memory signature
|
|
||||||
) = handlePermit2Approval(
|
|
||||||
WETH_ADDR, address(uniswapV3Exposed), amountIn
|
|
||||||
);
|
|
||||||
|
|
||||||
// Assume the permit2.approve method will be called from the TychoRouter
|
|
||||||
// Replicate this scenario in this test.
|
|
||||||
permit2.permit(ALICE, permitSingle, signature);
|
|
||||||
uint256 amountOut = uniswapV3Exposed.swap(amountIn, data);
|
|
||||||
vm.stopPrank();
|
|
||||||
|
|
||||||
assertGe(amountOut, expAmountOut);
|
|
||||||
assertEq(IERC20(WETH_ADDR).balanceOf(address(uniswapV3Exposed)), 0);
|
|
||||||
assertGe(IERC20(DAI_ADDR).balanceOf(address(this)), expAmountOut);
|
|
||||||
}
|
|
||||||
|
|
||||||
function testSwapFailureInvalidTarget() public {
|
function testSwapFailureInvalidTarget() public {
|
||||||
uint256 amountIn = 10 ** 18;
|
uint256 amountIn = 10 ** 18;
|
||||||
deal(WETH_ADDR, address(uniswapV3Exposed), amountIn);
|
deal(WETH_ADDR, address(uniswapV3Exposed), amountIn);
|
||||||
|
|||||||
@@ -722,7 +722,7 @@ mod tests {
|
|||||||
"a478c2975ab1ea89e8196811f51a7b7ade33eb11", // component id
|
"a478c2975ab1ea89e8196811f51a7b7ade33eb11", // component id
|
||||||
"3ede3eca2a72b3aecc820e955b36f38437d01395", // receiver
|
"3ede3eca2a72b3aecc820e955b36f38437d01395", // receiver
|
||||||
"00", // zero2one
|
"00", // zero2one
|
||||||
"00", // transfer method
|
"00", // transfer type
|
||||||
"00000000000000", // padding
|
"00000000000000", // padding
|
||||||
));
|
));
|
||||||
let hex_calldata = encode(&calldata);
|
let hex_calldata = encode(&calldata);
|
||||||
@@ -826,7 +826,7 @@ mod tests {
|
|||||||
"3ede3eca2a72b3aecc820e955b36f38437d01395", // receiver
|
"3ede3eca2a72b3aecc820e955b36f38437d01395", // receiver
|
||||||
"00", // zero2one
|
"00", // zero2one
|
||||||
"00", // exact out
|
"00", // exact out
|
||||||
"00", // transfer method
|
"00", // transfer type
|
||||||
"00000000000000000000000000", // padding
|
"00000000000000000000000000", // padding
|
||||||
));
|
));
|
||||||
let hex_calldata = encode(&calldata);
|
let hex_calldata = encode(&calldata);
|
||||||
@@ -1485,7 +1485,7 @@ mod tests {
|
|||||||
"3ede3eca2a72b3aecc820e955b36f38437d01395", // receiver
|
"3ede3eca2a72b3aecc820e955b36f38437d01395", // receiver
|
||||||
"00", // zero2one
|
"00", // zero2one
|
||||||
"00", // exact out
|
"00", // exact out
|
||||||
"00", // transfer method
|
"00", // transfer type
|
||||||
"00000000000000000000000000", // padding
|
"00000000000000000000000000", // padding
|
||||||
]
|
]
|
||||||
.join("");
|
.join("");
|
||||||
@@ -1569,7 +1569,7 @@ mod tests {
|
|||||||
"3ede3eca2a72b3aecc820e955b36f38437d01395", // receiver
|
"3ede3eca2a72b3aecc820e955b36f38437d01395", // receiver
|
||||||
"00", // zero2one
|
"00", // zero2one
|
||||||
"00", // exact out
|
"00", // exact out
|
||||||
"00", // transfer method
|
"00", // transfer type
|
||||||
"000000000000", // padding
|
"000000000000", // padding
|
||||||
]
|
]
|
||||||
.join("");
|
.join("");
|
||||||
@@ -1821,7 +1821,7 @@ mod tests {
|
|||||||
"3ede3eca2a72b3aecc820e955b36f38437d01395", // router address
|
"3ede3eca2a72b3aecc820e955b36f38437d01395", // router address
|
||||||
"88e6a0c2ddd26feeb64f039a2c41296fcb3f5640", // component id
|
"88e6a0c2ddd26feeb64f039a2c41296fcb3f5640", // component id
|
||||||
"01", // zero2one
|
"01", // zero2one
|
||||||
"00", // transfer method
|
"00", // transfer type
|
||||||
"006e", // ple encoded swaps
|
"006e", // ple encoded swaps
|
||||||
"01", // token in index
|
"01", // token in index
|
||||||
"00000000", // split
|
"00000000", // split
|
||||||
@@ -1832,7 +1832,7 @@ mod tests {
|
|||||||
"3ede3eca2a72b3aecc820e955b36f38437d01395", // router address
|
"3ede3eca2a72b3aecc820e955b36f38437d01395", // router address
|
||||||
"8ad599c3a0ff1de082011efddc58f1908eb6e6d8", // component id
|
"8ad599c3a0ff1de082011efddc58f1908eb6e6d8", // component id
|
||||||
"00", // zero2one
|
"00", // zero2one
|
||||||
"00", // transfer method
|
"00", // transfer type
|
||||||
]
|
]
|
||||||
.join("");
|
.join("");
|
||||||
|
|
||||||
@@ -1975,7 +1975,7 @@ mod tests {
|
|||||||
"3ede3eca2a72b3aecc820e955b36f38437d01395", // router address
|
"3ede3eca2a72b3aecc820e955b36f38437d01395", // router address
|
||||||
"88e6a0c2ddd26feeb64f039a2c41296fcb3f5640", // component id
|
"88e6a0c2ddd26feeb64f039a2c41296fcb3f5640", // component id
|
||||||
"01", // zero2one
|
"01", // zero2one
|
||||||
"00", // transfer method
|
"00", // transfer type
|
||||||
"006e", // ple encoded swaps
|
"006e", // ple encoded swaps
|
||||||
"00", // token in index
|
"00", // token in index
|
||||||
"01", // token out index
|
"01", // token out index
|
||||||
@@ -1987,7 +1987,7 @@ mod tests {
|
|||||||
"3ede3eca2a72b3aecc820e955b36f38437d01395", // router address
|
"3ede3eca2a72b3aecc820e955b36f38437d01395", // router address
|
||||||
"8ad599c3a0ff1de082011efddc58f1908eb6e6d8", // component id
|
"8ad599c3a0ff1de082011efddc58f1908eb6e6d8", // component id
|
||||||
"01", // zero2one
|
"01", // zero2one
|
||||||
"00", // transfer method
|
"00", // transfer type
|
||||||
"0057", // ple encoded swaps
|
"0057", // ple encoded swaps
|
||||||
"01", // token in index
|
"01", // token in index
|
||||||
"00", // token out index
|
"00", // token out index
|
||||||
@@ -1997,7 +1997,7 @@ mod tests {
|
|||||||
"b4e16d0168e52d35cacd2c6185b44281ec28c9dc", // component id,
|
"b4e16d0168e52d35cacd2c6185b44281ec28c9dc", // component id,
|
||||||
"3ede3eca2a72b3aecc820e955b36f38437d01395", // router address
|
"3ede3eca2a72b3aecc820e955b36f38437d01395", // router address
|
||||||
"00", // zero2one
|
"00", // zero2one
|
||||||
"00", // transfer method
|
"00", // transfer type
|
||||||
"00000000000000" // padding
|
"00000000000000" // padding
|
||||||
]
|
]
|
||||||
.join("");
|
.join("");
|
||||||
@@ -2135,7 +2135,7 @@ mod tests {
|
|||||||
"b4e16d0168e52d35cacd2c6185b44281ec28c9dc", // component id
|
"b4e16d0168e52d35cacd2c6185b44281ec28c9dc", // component id
|
||||||
"3ede3eca2a72b3aecc820e955b36f38437d01395", // router address
|
"3ede3eca2a72b3aecc820e955b36f38437d01395", // router address
|
||||||
"01", // zero2one
|
"01", // zero2one
|
||||||
"00", // transfer method
|
"00", // transfer type
|
||||||
"006e", // ple encoded swaps
|
"006e", // ple encoded swaps
|
||||||
"01", // token in index
|
"01", // token in index
|
||||||
"00", // token out index
|
"00", // token out index
|
||||||
@@ -2147,7 +2147,7 @@ mod tests {
|
|||||||
"3ede3eca2a72b3aecc820e955b36f38437d01395", // router address
|
"3ede3eca2a72b3aecc820e955b36f38437d01395", // router address
|
||||||
"88e6a0c2ddd26feeb64f039a2c41296fcb3f5640", // component id
|
"88e6a0c2ddd26feeb64f039a2c41296fcb3f5640", // component id
|
||||||
"00", // zero2one
|
"00", // zero2one
|
||||||
"00", // transfer method
|
"00", // transfer type
|
||||||
"006e", // ple encoded swaps
|
"006e", // ple encoded swaps
|
||||||
"01", // token in index
|
"01", // token in index
|
||||||
"00", // token out index
|
"00", // token out index
|
||||||
@@ -2159,7 +2159,7 @@ mod tests {
|
|||||||
"3ede3eca2a72b3aecc820e955b36f38437d01395", // router address
|
"3ede3eca2a72b3aecc820e955b36f38437d01395", // router address
|
||||||
"8ad599c3a0ff1de082011efddc58f1908eb6e6d8", // component id
|
"8ad599c3a0ff1de082011efddc58f1908eb6e6d8", // component id
|
||||||
"00", // zero2one
|
"00", // zero2one
|
||||||
"00", // transfer method
|
"00", // transfer type
|
||||||
"00000000000000" // padding
|
"00000000000000" // padding
|
||||||
]
|
]
|
||||||
.join("");
|
.join("");
|
||||||
|
|||||||
@@ -916,7 +916,7 @@ mod tests {
|
|||||||
"1d96f2f6bef1202e4ce1ff6dad0c2cb002861d3e",
|
"1d96f2f6bef1202e4ce1ff6dad0c2cb002861d3e",
|
||||||
// zero for one
|
// zero for one
|
||||||
"00",
|
"00",
|
||||||
// transfer method
|
// transfer type
|
||||||
"00",
|
"00",
|
||||||
))
|
))
|
||||||
);
|
);
|
||||||
|
|||||||
Reference in New Issue
Block a user