Skip to content

Commit

Permalink
Merge pull request #22 from 1inch/feature/SC-1281
Browse files Browse the repository at this point in the history
[SC-1281] change matcha2 tests for using AllowanceHolder contract
  • Loading branch information
ZumZoom authored Oct 15, 2024
2 parents b6bda10 + e5a657f commit 0737d9e
Show file tree
Hide file tree
Showing 9 changed files with 404 additions and 51 deletions.
100 changes: 50 additions & 50 deletions README.md

Large diffs are not rendered by default.

35 changes: 35 additions & 0 deletions contracts/interfaces/router/0xSettler/IAllowanceHolder.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

interface IAllowanceHolder {
/// @notice Executes against `target` with the `data` payload. Prior to execution, token permits
/// are temporarily stored for the duration of the transaction. These permits can be
/// consumed by the `operator` during the execution
/// @notice `operator` consumes the funds during its operations by calling back into
/// `AllowanceHolder` with `transferFrom`, consuming a token permit.
/// @dev Neither `exec` nor `transferFrom` check that `token` contains code.
/// @dev msg.sender is forwarded to target appended to the msg data (similar to ERC-2771)
/// @param operator An address which is allowed to consume the token permits
/// @param token The ERC20 token the caller has authorised to be consumed
/// @param amount The quantity of `token` the caller has authorised to be consumed
/// @param target A contract to execute operations with `data`
/// @param data The data to forward to `target`
/// @return result The returndata from calling `target` with `data`
/// @notice If calling `target` with `data` reverts, the revert is propagated
function exec(address operator, address token, uint256 amount, address payable target, bytes calldata data)
external
payable
returns (bytes memory result);

/// @notice The counterpart to `exec` which allows for the consumption of token permits later
/// during execution
/// @dev *DOES NOT* check that `token` contains code. This function vacuously succeeds if
/// `token` is empty.
/// @dev can only be called by the `operator` previously registered in `exec`
/// @param token The ERC20 token to transfer
/// @param owner The owner of tokens to transfer
/// @param recipient The destination/beneficiary of the ERC20 `transferFrom`
/// @param amount The quantity of `token` to transfer`
/// @return true
function transferFrom(address token, address owner, address recipient, uint256 amount) external returns (bool);
}
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import { ISignatureTransfer } from "../ISignatureTransfer.sol";
import { ISignatureTransfer } from "../../ISignatureTransfer.sol";

interface ISettlerActions {
/// @dev Transfer funds from msg.sender Permit2.
Expand Down
72 changes: 72 additions & 0 deletions test/RouterMixedPools.js
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,42 @@ describe('Mixed pools', async function () {
gasUsedTable.addElementToRow(gasUsedTableRow, ProtocolKey.INCH, (await tx.wait()).gasUsed);
});

it('settler', async function () {
const { addr1, tokens, settler, allowanceHolder, fakePermit, iSettlerActions } = await loadFixture(initRouterContracts);

const encodedTransferFrom = iSettlerActions.encodeFunctionData('TRANSFER_FROM', [
UniswapV2Pools.WETH_DAI,
fakePermit({ permitted: { token: tokens.DAI.target, amount } }),
'0x',
]);

const encodedDAIToWETH = iSettlerActions.encodeFunctionData('UNISWAPV2', [
settler.target,
tokens.DAI.target,
0n,
UniswapV2Pools.WETH_DAI,
0x1e01n,
0n,
]);

const encodedWETHToUSDC = iSettlerActions.encodeFunctionData('UNISWAPV3', [
addr1.address,
10000n,
encodeUniswapPath(tokens.WETH.target, 0x00n, UniswapV3Pools.WETH_USDC.fee, tokens.USDC.target),
0n,
]);

const swapCalldata = settler.interface.encodeFunctionData('execute', [
{ recipient: constants.ZERO_ADDRESS, buyToken: constants.ZERO_ADDRESS, minAmountOut: '0x00' },
[encodedTransferFrom, encodedDAIToWETH, encodedWETHToUSDC],
constants.ZERO_BYTES32,
]);

const tx = await allowanceHolder.exec(settler.target, tokens.DAI.target, amount, settler.target, swapCalldata);

gasUsedTable.addElementToRow(gasUsedTableRow, ProtocolKey.SETTLER, (await tx.wait()).gasUsed);
});

it('uniswap', async function () {
const { addr1, uniswapUniversal, tokens } = await loadFixture(initRouterContracts);

Expand Down Expand Up @@ -222,6 +258,42 @@ describe('Mixed pools', async function () {
gasUsedTable.addElementToRow(gasUsedTableRow, ProtocolKey.INCH, (await tx.wait()).gasUsed);
});

it('settler', async function () {
const { addr1, tokens, settler, allowanceHolder, fakePermit, iSettlerActions } = await loadFixture(initRouterContracts);

const encodedTransferFrom = iSettlerActions.encodeFunctionData('TRANSFER_FROM', [
settler.target,
fakePermit({ permitted: { token: tokens.DAI.target, amount } }),
'0x',
]);

const encodedDAIToWETH = iSettlerActions.encodeFunctionData('UNISWAPV3', [
UniswapV2Pools.WETH_USDC, // recipient, use WETH_USDC pool to save gas
10000n,
encodeUniswapPath(tokens.DAI.target, 0x00n, UniswapV3Pools.WETH_DAI.fee, tokens.WETH.target),
0n,
]);

const encodedWETHToUSDC = iSettlerActions.encodeFunctionData('UNISWAPV2', [
addr1.address,
tokens.WETH.target,
0n,
UniswapV2Pools.WETH_USDC,
0x1e00n,
0n,
]);

const swapCalldata = settler.interface.encodeFunctionData('execute', [
{ recipient: constants.ZERO_ADDRESS, buyToken: constants.ZERO_ADDRESS, minAmountOut: '0x00' },
[encodedTransferFrom, encodedDAIToWETH, encodedWETHToUSDC],
constants.ZERO_BYTES32,
]);

const tx = await allowanceHolder.exec(settler.target, tokens.DAI.target, amount, settler.target, swapCalldata);

gasUsedTable.addElementToRow(gasUsedTableRow, ProtocolKey.SETTLER, (await tx.wait()).gasUsed);
});

it('uniswap', async function () {
const { addr1, uniswapUniversal, tokens } = await loadFixture(initRouterContracts);

Expand Down
135 changes: 135 additions & 0 deletions test/RouterUniV2.js
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,39 @@ describe('Router [UniV2]', async function () {
gasUsedTable.addElementToRow(gasUsedTableRow, ProtocolKey.MATCHA, (await tx.wait()).gasUsed);
});

it('settler', async function () {
const { addr1, tokens, settler, allowanceHolder, fakePermit, iSettlerActions } = await loadFixture(initRouterContracts);

const encodedTransferFrom = iSettlerActions.encodeFunctionData('TRANSFER_FROM', [UniswapV2Pools.WETH_DAI, fakePermit(), '0x']);

const encodedUniswapV2FunctionDataDAItoWETH = iSettlerActions.encodeFunctionData('UNISWAPV2', [
settler.target, // since we'll need to unwrap it
tokens.DAI.target, // sell token
0n, // bps
UniswapV2Pools.WETH_DAI, // pool
0x1e01n, // swapInfo
0n, // amountOutMin
]);

const encodedBasicFunctionData = iSettlerActions.encodeFunctionData('BASIC', [
tokens.WETH.target,
10000n, // bps
tokens.WETH.target, // pool
4n, // offset
tokens.WETH.interface.getFunction('withdraw').selector + trim0x(constants.ZERO_BYTES32),
]);

const swapCalldata = settler.interface.encodeFunctionData('execute', [
{ recipient: addr1.address, buyToken: await tokens.EEE.getAddress(), minAmountOut: '0x00' },
[encodedTransferFrom, encodedUniswapV2FunctionDataDAItoWETH, encodedBasicFunctionData],
constants.ZERO_BYTES32,
]);

const tx = await allowanceHolder.exec(settler.target, tokens.DAI.target, ether('1'), settler.target, swapCalldata);

gasUsedTable.addElementToRow(gasUsedTableRow, ProtocolKey.SETTLER, (await tx.wait()).gasUsed);
});

it('uniswap universal router', async function () {
const { addr1, tokens, uniswapUniversal } = await loadFixture(initRouterContracts);

Expand Down Expand Up @@ -324,6 +357,31 @@ describe('Router [UniV2]', async function () {
gasUsedTable.addElementToRow(gasUsedTableRow, ProtocolKey.MATCHA, (await tx.wait()).gasUsed);
});

it('settler', async function () {
const { addr1, tokens, settler, allowanceHolder, fakePermit, iSettlerActions } = await loadFixture(initRouterContracts);

const encodedTransferFrom = iSettlerActions.encodeFunctionData('TRANSFER_FROM', [UniswapV2Pools.WETH_DAI, fakePermit(), '0x']);

const encodedUniswapV2FunctionDataDAItoWETH = iSettlerActions.encodeFunctionData('UNISWAPV2', [
addr1.address, // recipient
tokens.DAI.target, // sell token
0n, // bps
UniswapV2Pools.WETH_DAI, // pool
0x1e01n, // swapInfo
0n, // amountOutMin
]);

const swapCalldata = settler.interface.encodeFunctionData('execute', [
{ recipient: constants.ZERO_ADDRESS, buyToken: constants.ZERO_ADDRESS, minAmountOut: '0x00' },
[encodedTransferFrom, encodedUniswapV2FunctionDataDAItoWETH],
constants.ZERO_BYTES32,
]);

const tx = await allowanceHolder.exec(settler.target, tokens.DAI.target, ether('1'), settler.target, swapCalldata);

gasUsedTable.addElementToRow(gasUsedTableRow, ProtocolKey.SETTLER, (await tx.wait()).gasUsed);
});

it('uniswap universal router', async function () {
const { addr1, tokens, uniswapUniversal } = await loadFixture(initRouterContracts);

Expand Down Expand Up @@ -394,6 +452,40 @@ describe('Router [UniV2]', async function () {
gasUsedTable.addElementToRow(gasUsedTableRow, ProtocolKey.MATCHA, (await tx.wait()).gasUsed);
});

it('settler', async function () {
const { addr1, tokens, settler, allowanceHolder, fakePermit, iSettlerActions } = await loadFixture(initRouterContracts);

const encodedTransferFrom = iSettlerActions.encodeFunctionData('TRANSFER_FROM', [UniswapV2Pools.WETH_DAI, fakePermit(), '0x']);

const UniswapV2FunctionDataDAItoWETH = iSettlerActions.encodeFunctionData('UNISWAPV2', [
UniswapV2Pools.WETH_USDC,
tokens.DAI.target, // sell token
0n, // bps
UniswapV2Pools.WETH_DAI, // pool
0x1e01n, // swapInfo
0n, // amountOutMin
]);

const UniswapV2FunctionDataWETHtoUSDC = iSettlerActions.encodeFunctionData('UNISWAPV2', [
addr1.address,
tokens.WETH.target,
0n,
UniswapV2Pools.WETH_USDC,
0x1e00,
0n,
]);

const swapCalldata = settler.interface.encodeFunctionData('execute', [
{ recipient: constants.ZERO_ADDRESS, buyToken: constants.ZERO_ADDRESS, minAmountOut: '0x00' },
[encodedTransferFrom, UniswapV2FunctionDataDAItoWETH, UniswapV2FunctionDataWETHtoUSDC],
constants.ZERO_BYTES32,
]);

const tx = await allowanceHolder.exec(settler.target, tokens.DAI.target, ether('1'), settler.target, swapCalldata);

gasUsedTable.addElementToRow(gasUsedTableRow, ProtocolKey.SETTLER, (await tx.wait()).gasUsed);
});

it('uniswap universal router', async function () {
const { addr1, tokens, uniswapUniversal } = await loadFixture(initRouterContracts);

Expand Down Expand Up @@ -468,6 +560,49 @@ describe('Router [UniV2]', async function () {
gasUsedTable.addElementToRow(gasUsedTableRow, ProtocolKey.MATCHA, (await tx.wait()).gasUsed);
});

it('settler', async function () {
const { addr1, tokens, settler, allowanceHolder, fakePermit, iSettlerActions } = await loadFixture(initRouterContracts);

const encodedTransferFrom = iSettlerActions.encodeFunctionData('TRANSFER_FROM', [UniswapV2Pools.WETH_DAI, fakePermit(), '0x']);

const UniswapV2FunctionDataDAItoWETH = iSettlerActions.encodeFunctionData('UNISWAPV2', [
UniswapV2Pools.WETH_USDC,
tokens.DAI.target, // sell token
0n, // bps
UniswapV2Pools.WETH_DAI, // pool
0x1e01n, // swapInfo
0n, // amountOutMin
]);

const UniswapV2FunctionDataWETHtoUSDC = iSettlerActions.encodeFunctionData('UNISWAPV2', [
UniswapV2Pools.USDC_USDT,
tokens.WETH.target,
0n,
UniswapV2Pools.WETH_USDC,
0x1e00n,
0n,
]);

const UniswapV2FunctionDataUSDCtoUSDT = iSettlerActions.encodeFunctionData('UNISWAPV2', [
addr1.address,
tokens.USDC.target,
0n,
UniswapV2Pools.USDC_USDT,
0x1e01n,
0n,
]);

const swapCalldata = settler.interface.encodeFunctionData('execute', [
{ recipient: constants.ZERO_ADDRESS, buyToken: constants.ZERO_ADDRESS, minAmountOut: '0x00' },
[encodedTransferFrom, UniswapV2FunctionDataDAItoWETH, UniswapV2FunctionDataWETHtoUSDC, UniswapV2FunctionDataUSDCtoUSDT],
constants.ZERO_BYTES32,
]);

const tx = await allowanceHolder.exec(settler.target, tokens.DAI.target, ether('1'), settler.target, swapCalldata);

gasUsedTable.addElementToRow(gasUsedTableRow, ProtocolKey.SETTLER, (await tx.wait()).gasUsed);
});

it('uniswap universal router', async function () {
const { addr1, tokens, uniswapUniversal } = await loadFixture(initRouterContracts);

Expand Down
Loading

0 comments on commit 0737d9e

Please sign in to comment.