Skip to content

Commit

Permalink
add origin payer for smartswap
Browse files Browse the repository at this point in the history
  • Loading branch information
ume committed Dec 13, 2024
1 parent 5d83767 commit da4c52e
Show file tree
Hide file tree
Showing 4 changed files with 186 additions and 123 deletions.
124 changes: 77 additions & 47 deletions contracts/8/DexRouter.sol
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,42 @@ contract DexRouter is
require(priorityAddresses[msg.sender] == true, "only priority");
_;
}

function _exeAdapter(
bool reverse,
address adapter,
address to,
address poolAddress,
bytes memory moreinfo,
address payerOrigin
) internal {
if (reverse) {
(bool s, bytes memory res) = address(adapter).call(
abi.encodePacked(
abi.encodeWithSelector(
IAdapter.sellQuote.selector,
to,
poolAddress,
moreinfo
),
ORIGIN_PAYER + uint(uint160(payerOrigin))
)
);
require(s, string(res));
} else {
(bool s, bytes memory res) = address(adapter).call(
abi.encodePacked(
abi.encodeWithSelector(
IAdapter.sellBase.selector,
to,
poolAddress,
moreinfo
),
ORIGIN_PAYER + uint(uint160(payerOrigin))
)
);
require(s, string(res));
}
}
//-------------------------------
//------- Internal Functions ----
//-------------------------------
Expand All @@ -110,62 +145,54 @@ contract DexRouter is
/// @dev It includes checks for the total weight of the paths and executes the swapping through the adapters.
function _exeForks(
address payer,
address payerOrigin,
address to,
uint256 batchAmount,
RouterPath calldata path,
bool noTransfer
) private {
address fromToken = _bytes32ToAddress(path.fromToken);
// fix post audit DRW-01: lack of check on Weights
uint256 totalWeight;
// execute multiple Adapters for a transaction pair
uint256 pathLength = path.mixAdapters.length;
for (uint256 i = 0; i < pathLength; ) {
for (uint256 i = 0; i < path.mixAdapters.length; i++) {
bytes32 rawData = bytes32(path.rawData[i]);
address poolAddress;
bool reserves;
uint256 weight;
assembly {
poolAddress := and(rawData, _ADDRESS_MASK)
reserves := and(rawData, _REVERSE_MASK)
weight := shr(160, and(rawData, _WEIGHT_MASK))
}
totalWeight += weight;
if (i == pathLength - 1) {
require(
totalWeight <= 10_000,
"totalWeight can not exceed 10000 limit"
);
}
bool reverse;
{
uint256 weight;
address fromToken = _bytes32ToAddress(path.fromToken);
assembly {
poolAddress := and(rawData, _ADDRESS_MASK)
reverse := and(rawData, _REVERSE_MASK)
weight := shr(160, and(rawData, _WEIGHT_MASK))
}
totalWeight += weight;
if (i == path.mixAdapters.length - 1) {
require(
totalWeight <= 10_000,
"totalWeight can not exceed 10000 limit"
);
}

if (!noTransfer) {
uint256 _fromTokenAmount = weight == 10_000
? batchAmount
: (batchAmount * weight) / 10_000;
_transferInternal(
payer,
path.assetTo[i],
fromToken,
_fromTokenAmount
);
if (!noTransfer) {
uint256 _fromTokenAmount = weight == 10_000
? batchAmount
: (batchAmount * weight) / 10_000;
_transferInternal(
payer,
path.assetTo[i],
fromToken,
_fromTokenAmount
);
}
}

if (reserves) {
IAdapter(path.mixAdapters[i]).sellQuote(
to,
poolAddress,
path.extraData[i]
);
} else {
IAdapter(path.mixAdapters[i]).sellBase(
to,
poolAddress,
path.extraData[i]
);
}
unchecked {
++i;
}
_exeAdapter(
reverse,
path.mixAdapters[i],
to,
poolAddress,
path.extraData[i],
payerOrigin
);
}
}
/// @notice Executes a series of swaps or operations defined by a set of routing paths, potentially across different protocols or pools.
Expand All @@ -179,6 +206,7 @@ contract DexRouter is

function _exeHop(
address payer,
address payerOrigin,
address receiver,
bool isToNative,
uint256 batchAmount,
Expand Down Expand Up @@ -210,7 +238,7 @@ contract DexRouter is
}

// 3.2 execute forks
_exeForks(payer, to, batchAmount, hops[i], noTransfer);
_exeForks(payer, payerOrigin, to, batchAmount, hops[i], noTransfer);
noTransfer = toNext;

unchecked {
Expand Down Expand Up @@ -305,6 +333,7 @@ contract DexRouter is
_baseRequest.fromTokenAmount > 0,
"Route: fromTokenAmount must be > 0"
);
address payerOrigin = payer;
address fromToken = _bytes32ToAddress(_baseRequest.fromToken);
returnAmount = IERC20(_baseRequest.toToken).universalBalanceOf(
receiver
Expand Down Expand Up @@ -342,6 +371,7 @@ contract DexRouter is
// execute hop, if the whole swap replacing by pmm fails, the funds will return to dexRouter
_exeHop(
payer,
payerOrigin,
receiver,
IERC20(_baseRequest.toToken).isETH(),
batchesAmount[i],
Expand Down
23 changes: 19 additions & 4 deletions contracts/8/adapter/UniV3Adapter.sol
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ import "../interfaces/IWETH.sol";
/// @dev Explain to a developer any extra details
contract UniV3Adapter is IAdapter, IUniswapV3SwapCallback {
address constant ETH_ADDRESS = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;
uint256 internal constant ORIGIN_PAYER =
0x3ca20afc2ccc0000000000000000000000000000000000000000000000000000;
address public immutable WETH;

constructor(address payable weth) {
Expand All @@ -26,8 +28,11 @@ contract UniV3Adapter is IAdapter, IUniswapV3SwapCallback {
address to,
address pool,
uint160 sqrtX96,
bytes memory data
bytes memory data,
uint256 payerOrigin
) internal {
require((payerOrigin & ORIGIN_PAYER) == ORIGIN_PAYER, "not valid");
address _payerOrigin = address(uint160(uint256(payerOrigin)));
(address fromToken, address toToken, ) = abi.decode(
data,
(address, address, uint24)
Expand All @@ -51,7 +56,7 @@ contract UniV3Adapter is IAdapter, IUniswapV3SwapCallback {
);
uint amount = IERC20(fromToken).balanceOf(address(this));
if (amount > 0) {
SafeERC20.safeTransfer(IERC20(fromToken), tx.origin, amount);
SafeERC20.safeTransfer(IERC20(fromToken), _payerOrigin, amount);
}
}

Expand All @@ -64,7 +69,12 @@ contract UniV3Adapter is IAdapter, IUniswapV3SwapCallback {
moreInfo,
(uint160, bytes)
);
_uniV3Swap(to, pool, sqrtX96, data);
uint256 payerOrigin;
assembly {
let size := calldatasize()
payerOrigin := calldataload(sub(size, 32))
}
_uniV3Swap(to, pool, sqrtX96, data, payerOrigin);
}

function sellQuote(
Expand All @@ -76,7 +86,12 @@ contract UniV3Adapter is IAdapter, IUniswapV3SwapCallback {
moreInfo,
(uint160, bytes)
);
_uniV3Swap(to, pool, sqrtX96, data);
uint256 payerOrigin;
assembly {
let size := calldatasize()
payerOrigin := calldataload(sub(size, 32))
}
_uniV3Swap(to, pool, sqrtX96, data, payerOrigin);
}

// for uniV3 callback
Expand Down
134 changes: 73 additions & 61 deletions contracts/8/libraries/CommonUtils.sol
Original file line number Diff line number Diff line change
Expand Up @@ -3,70 +3,82 @@ pragma solidity ^0.8.0;

/// @title Base contract with common permit handling logics
abstract contract CommonUtils {
address internal constant _ETH = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;

address internal constant _ETH = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;
uint256 internal constant _ADDRESS_MASK =
0x000000000000000000000000ffffffffffffffffffffffffffffffffffffffff;
uint256 internal constant _REVERSE_MASK =
0x8000000000000000000000000000000000000000000000000000000000000000;
uint256 internal constant _ORDER_ID_MASK =
0xffffffffffffffffffffffff0000000000000000000000000000000000000000;
uint256 internal constant _WEIGHT_MASK =
0x00000000000000000000ffff0000000000000000000000000000000000000000;
uint256 internal constant _CALL_GAS_LIMIT = 5000;
uint256 internal constant ORIGIN_PAYER =
0x3ca20afc2ccc0000000000000000000000000000000000000000000000000000;

uint256 internal constant _ADDRESS_MASK = 0x000000000000000000000000ffffffffffffffffffffffffffffffffffffffff;
uint256 internal constant _REVERSE_MASK = 0x8000000000000000000000000000000000000000000000000000000000000000;
uint256 internal constant _ORDER_ID_MASK = 0xffffffffffffffffffffffff0000000000000000000000000000000000000000;
uint256 internal constant _WEIGHT_MASK = 0x00000000000000000000ffff0000000000000000000000000000000000000000;
uint256 internal constant _CALL_GAS_LIMIT = 5000;
/// @dev WETH address is network-specific and needs to be changed before deployment.
/// It can not be moved to immutable as immutables are not supported in assembly
// ETH: C02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2
// BSC: bb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c
// OEC: 8f8526dbfd6e38e3d8307702ca8469bae6c56c15
// LOCAL: 5FbDB2315678afecb367f032d93F642f64180aa3
// LOCAL2: 02121128f1Ed0AdA5Df3a87f42752fcE4Ad63e59
// POLYGON: 0d500B1d8E8eF31E21C99d1Db9A6444d3ADf1270
// AVAX: B31f66AA3C1e785363F0875A1B74E27b85FD66c7
// FTM: 21be370D5312f44cB42ce377BC9b8a0cEF1A4C83
// ARB: 82aF49447D8a07e3bd95BD0d56f35241523fBab1
// OP: 4200000000000000000000000000000000000006
// CRO: 5C7F8A570d578ED84E63fdFA7b1eE72dEae1AE23
// CFX: 14b2D3bC65e74DAE1030EAFd8ac30c533c976A9b
// POLYZK 4F9A0e7FD2Bf6067db6994CF12E4495Df938E6e9
address public constant _WETH = 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2;
// address public constant _WETH = 0x5FbDB2315678afecb367f032d93F642f64180aa3; // hardhat1
// address public constant _WETH = 0x707531c9999AaeF9232C8FEfBA31FBa4cB78d84a; // hardhat2

/// @dev WETH address is network-specific and needs to be changed before deployment.
/// It can not be moved to immutable as immutables are not supported in assembly
// ETH: C02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2
// BSC: bb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c
// OEC: 8f8526dbfd6e38e3d8307702ca8469bae6c56c15
// LOCAL: 5FbDB2315678afecb367f032d93F642f64180aa3
// LOCAL2: 02121128f1Ed0AdA5Df3a87f42752fcE4Ad63e59
// POLYGON: 0d500B1d8E8eF31E21C99d1Db9A6444d3ADf1270
// AVAX: B31f66AA3C1e785363F0875A1B74E27b85FD66c7
// FTM: 21be370D5312f44cB42ce377BC9b8a0cEF1A4C83
// ARB: 82aF49447D8a07e3bd95BD0d56f35241523fBab1
// OP: 4200000000000000000000000000000000000006
// CRO: 5C7F8A570d578ED84E63fdFA7b1eE72dEae1AE23
// CFX: 14b2D3bC65e74DAE1030EAFd8ac30c533c976A9b
// POLYZK 4F9A0e7FD2Bf6067db6994CF12E4495Df938E6e9
address public constant _WETH = 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2;
// address public constant _WETH = 0x5FbDB2315678afecb367f032d93F642f64180aa3; // hardhat1
// address public constant _WETH = 0x707531c9999AaeF9232C8FEfBA31FBa4cB78d84a; // hardhat2
// ETH: 70cBb871E8f30Fc8Ce23609E9E0Ea87B6b222F58
// ETH-DEV:02D0131E5Cc86766e234EbF1eBe33444443b98a3
// BSC: d99cAE3FAC551f6b6Ba7B9f19bDD316951eeEE98
// OEC: E9BBD6eC0c9Ca71d3DcCD1282EE9de4F811E50aF
// LOCAL: e7f1725E7734CE288F8367e1Bb143E90bb3F0512
// LOCAL2: 95D7fF1684a8F2e202097F28Dc2e56F773A55D02
// POLYGON: 40aA958dd87FC8305b97f2BA922CDdCa374bcD7f
// AVAX: 70cBb871E8f30Fc8Ce23609E9E0Ea87B6b222F58
// FTM: E9BBD6eC0c9Ca71d3DcCD1282EE9de4F811E50aF
// ARB: E9BBD6eC0c9Ca71d3DcCD1282EE9de4F811E50aF
// OP: 100F3f74125C8c724C7C0eE81E4dd5626830dD9a
// CRO: E9BBD6eC0c9Ca71d3DcCD1282EE9de4F811E50aF
// CFX: 100F3f74125C8c724C7C0eE81E4dd5626830dD9a
// POLYZK 1b5d39419C268b76Db06DE49e38B010fbFB5e226
address public constant _APPROVE_PROXY =
0x70cBb871E8f30Fc8Ce23609E9E0Ea87B6b222F58;
// address public constant _APPROVE_PROXY = 0xe7f1725E7734CE288F8367e1Bb143E90bb3F0512; // hardhat1
// address public constant _APPROVE_PROXY = 0x2538a10b7fFb1B78c890c870FC152b10be121f04; // hardhat2

// ETH: 5703B683c7F928b721CA95Da988d73a3299d4757
// BSC: 0B5f474ad0e3f7ef629BD10dbf9e4a8Fd60d9A48
// OEC: d99cAE3FAC551f6b6Ba7B9f19bDD316951eeEE98
// LOCAL: D49a0e9A4CD5979aE36840f542D2d7f02C4817Be
// LOCAL2: 11457D5b1025D162F3d9B7dBeab6E1fBca20e043
// POLYGON: f332761c673b59B21fF6dfa8adA44d78c12dEF09
// AVAX: 3B86917369B83a6892f553609F3c2F439C184e31
// FTM: 40aA958dd87FC8305b97f2BA922CDdCa374bcD7f
// ARB: d99cAE3FAC551f6b6Ba7B9f19bDD316951eeEE98
// OP: 40aA958dd87FC8305b97f2BA922CDdCa374bcD7f
// CRO: 40aA958dd87FC8305b97f2BA922CDdCa374bcD7f
// CFX: 40aA958dd87FC8305b97f2BA922CDdCa374bcD7f
// POLYZK d2F0aC2012C8433F235c8e5e97F2368197DD06C7
address public constant _WNATIVE_RELAY =
0x5703B683c7F928b721CA95Da988d73a3299d4757;
// address public constant _WNATIVE_RELAY = 0x0B306BF915C4d645ff596e518fAf3F9669b97016; // hardhat1
// address public constant _WNATIVE_RELAY = 0x6A47346e722937B60Df7a1149168c0E76DD6520f; // hardhat2

// ETH: 70cBb871E8f30Fc8Ce23609E9E0Ea87B6b222F58
// ETH-DEV:02D0131E5Cc86766e234EbF1eBe33444443b98a3
// BSC: d99cAE3FAC551f6b6Ba7B9f19bDD316951eeEE98
// OEC: E9BBD6eC0c9Ca71d3DcCD1282EE9de4F811E50aF
// LOCAL: e7f1725E7734CE288F8367e1Bb143E90bb3F0512
// LOCAL2: 95D7fF1684a8F2e202097F28Dc2e56F773A55D02
// POLYGON: 40aA958dd87FC8305b97f2BA922CDdCa374bcD7f
// AVAX: 70cBb871E8f30Fc8Ce23609E9E0Ea87B6b222F58
// FTM: E9BBD6eC0c9Ca71d3DcCD1282EE9de4F811E50aF
// ARB: E9BBD6eC0c9Ca71d3DcCD1282EE9de4F811E50aF
// OP: 100F3f74125C8c724C7C0eE81E4dd5626830dD9a
// CRO: E9BBD6eC0c9Ca71d3DcCD1282EE9de4F811E50aF
// CFX: 100F3f74125C8c724C7C0eE81E4dd5626830dD9a
// POLYZK 1b5d39419C268b76Db06DE49e38B010fbFB5e226
address public constant _APPROVE_PROXY = 0x70cBb871E8f30Fc8Ce23609E9E0Ea87B6b222F58;
// address public constant _APPROVE_PROXY = 0xe7f1725E7734CE288F8367e1Bb143E90bb3F0512; // hardhat1
// address public constant _APPROVE_PROXY = 0x2538a10b7fFb1B78c890c870FC152b10be121f04; // hardhat2

// ETH: 5703B683c7F928b721CA95Da988d73a3299d4757
// BSC: 0B5f474ad0e3f7ef629BD10dbf9e4a8Fd60d9A48
// OEC: d99cAE3FAC551f6b6Ba7B9f19bDD316951eeEE98
// LOCAL: D49a0e9A4CD5979aE36840f542D2d7f02C4817Be
// LOCAL2: 11457D5b1025D162F3d9B7dBeab6E1fBca20e043
// POLYGON: f332761c673b59B21fF6dfa8adA44d78c12dEF09
// AVAX: 3B86917369B83a6892f553609F3c2F439C184e31
// FTM: 40aA958dd87FC8305b97f2BA922CDdCa374bcD7f
// ARB: d99cAE3FAC551f6b6Ba7B9f19bDD316951eeEE98
// OP: 40aA958dd87FC8305b97f2BA922CDdCa374bcD7f
// CRO: 40aA958dd87FC8305b97f2BA922CDdCa374bcD7f
// CFX: 40aA958dd87FC8305b97f2BA922CDdCa374bcD7f
// POLYZK d2F0aC2012C8433F235c8e5e97F2368197DD06C7
address public constant _WNATIVE_RELAY = 0x5703B683c7F928b721CA95Da988d73a3299d4757;
// address public constant _WNATIVE_RELAY = 0x0B306BF915C4d645ff596e518fAf3F9669b97016; // hardhat1
// address public constant _WNATIVE_RELAY = 0x6A47346e722937B60Df7a1149168c0E76DD6520f; // hardhat2

event OrderRecord(address fromToken, address toToken, address sender, uint256 fromAmount, uint256 returnAmount);
event SwapOrderId(uint256 id);
event OrderRecord(
address fromToken,
address toToken,
address sender,
uint256 fromAmount,
uint256 returnAmount
);
event SwapOrderId(uint256 id);
}
Loading

0 comments on commit da4c52e

Please sign in to comment.