编译器
0.8.21+commit.d9974bed
文件 1 的 23:Address.sol
pragma solidity ^0.8.1;
library Address {
function isContract(address account) internal view returns (bool) {
return account.code.length > 0;
}
function sendValue(address payable recipient, uint256 amount) internal {
require(address(this).balance >= amount, "Address: insufficient balance");
(bool success, ) = recipient.call{value: amount}("");
require(success, "Address: unable to send value, recipient may have reverted");
}
function functionCall(address target, bytes memory data) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0, "Address: low-level call failed");
}
function functionCall(
address target,
bytes memory data,
string memory errorMessage
) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0, errorMessage);
}
function functionCallWithValue(
address target,
bytes memory data,
uint256 value
) internal returns (bytes memory) {
return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
}
function functionCallWithValue(
address target,
bytes memory data,
uint256 value,
string memory errorMessage
) internal returns (bytes memory) {
require(address(this).balance >= value, "Address: insufficient balance for call");
(bool success, bytes memory returndata) = target.call{value: value}(data);
return verifyCallResultFromTarget(target, success, returndata, errorMessage);
}
function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
return functionStaticCall(target, data, "Address: low-level static call failed");
}
function functionStaticCall(
address target,
bytes memory data,
string memory errorMessage
) internal view returns (bytes memory) {
(bool success, bytes memory returndata) = target.staticcall(data);
return verifyCallResultFromTarget(target, success, returndata, errorMessage);
}
function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
return functionDelegateCall(target, data, "Address: low-level delegate call failed");
}
function functionDelegateCall(
address target,
bytes memory data,
string memory errorMessage
) internal returns (bytes memory) {
(bool success, bytes memory returndata) = target.delegatecall(data);
return verifyCallResultFromTarget(target, success, returndata, errorMessage);
}
function verifyCallResultFromTarget(
address target,
bool success,
bytes memory returndata,
string memory errorMessage
) internal view returns (bytes memory) {
if (success) {
if (returndata.length == 0) {
require(isContract(target), "Address: call to non-contract");
}
return returndata;
} else {
_revert(returndata, errorMessage);
}
}
function verifyCallResult(
bool success,
bytes memory returndata,
string memory errorMessage
) internal pure returns (bytes memory) {
if (success) {
return returndata;
} else {
_revert(returndata, errorMessage);
}
}
function _revert(bytes memory returndata, string memory errorMessage) private pure {
if (returndata.length > 0) {
assembly {
let returndata_size := mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert(errorMessage);
}
}
}
文件 2 的 23:AlgebraCallback.sol
pragma solidity =0.8.21;
contract AlgebraCallback {
function algebraSwapCallback(int256 amount0Delta, int256 amount1Delta, bytes calldata data) external {
assembly {
let freeMemoryPointer := mload(0x40)
let token := calldataload(data.offset)
mstore(freeMemoryPointer, 0xa9059cbb00000000000000000000000000000000000000000000000000000000)
mstore(add(freeMemoryPointer, 4), and(caller(), 0xffffffffffffffffffffffffffffffffffffffff))
switch slt(amount0Delta, 0)
case 0 { mstore(add(freeMemoryPointer, 36), amount0Delta) }
default { mstore(add(freeMemoryPointer, 36), amount1Delta) }
if iszero(
and(
or(and(eq(mload(0), 1), gt(returndatasize(), 31)), iszero(returndatasize())),
call(gas(), token, 0, freeMemoryPointer, 68, 0, 32)
)
) {
revert(0, 0)
}
}
}
}
文件 3 的 23:ApeSwapCallback.sol
pragma solidity =0.8.21;
contract ApeSwapCallback {
bytes4 private constant _UNISWAP_PAIR_RESERVES_CALL_SELECTOR = 0x0902f1ac;
function apeCall(address, uint256 amount0, uint256 amount1, bytes calldata data) external {
assembly {
let freeMemoryPointer := mload(0x40)
let token := calldataload(data.offset)
let fee := calldataload(add(data.offset, 0x20))
mstore(freeMemoryPointer, _UNISWAP_PAIR_RESERVES_CALL_SELECTOR)
if iszero(staticcall(gas(), caller(), freeMemoryPointer, 0x4, freeMemoryPointer, 0x40)) {
revert(0, 0)
}
if iszero(eq(returndatasize(), 0x60)) {
mstore(0, 0x85cd58dc00000000000000000000000000000000000000000000000000000000)
revert(0, 4)
}
let reserve0 := mload(freeMemoryPointer)
let reserve1 := mload(add(freeMemoryPointer, 0x20))
mstore(freeMemoryPointer, 0xa9059cbb00000000000000000000000000000000000000000000000000000000)
mstore(add(freeMemoryPointer, 4), and(caller(), 0xffffffffffffffffffffffffffffffffffffffff))
switch eq(amount1, 0)
case 0 {
mstore(
add(freeMemoryPointer, 36),
add(div(mul(mul(reserve0, amount1), 100000), mul(sub(reserve1, amount1), sub(100000, fee))), 1)
)
}
default {
mstore(
add(freeMemoryPointer, 36),
add(div(mul(mul(reserve1, amount0), 100000), mul(sub(reserve0, amount0), sub(100000, fee))), 1)
)
}
if iszero(
and(
or(and(eq(mload(0), 1), gt(returndatasize(), 31)), iszero(returndatasize())),
call(gas(), token, 0, freeMemoryPointer, 68, 0, 32)
)
) {
revert(0, 0)
}
}
}
}
文件 4 的 23:ConvergenceXCallback.sol
pragma solidity =0.8.21;
contract ConvergenceXCallback {
bytes4 private constant _UNISWAP_PAIR_RESERVES_CALL_SELECTOR = 0x0902f1ac;
function swapCall(address, uint256 amount0, uint256 amount1, bytes calldata data) external {
assembly {
let freeMemoryPointer := mload(0x40)
let token := calldataload(data.offset)
let fee := calldataload(add(data.offset, 0x20))
mstore(freeMemoryPointer, _UNISWAP_PAIR_RESERVES_CALL_SELECTOR)
if iszero(staticcall(gas(), caller(), freeMemoryPointer, 0x4, freeMemoryPointer, 0x40)) {
revert(0, 0)
}
if iszero(eq(returndatasize(), 0x60)) {
mstore(0, 0x85cd58dc00000000000000000000000000000000000000000000000000000000)
revert(0, 4)
}
let reserve0 := mload(freeMemoryPointer)
let reserve1 := mload(add(freeMemoryPointer, 0x20))
mstore(freeMemoryPointer, 0xa9059cbb00000000000000000000000000000000000000000000000000000000)
mstore(add(freeMemoryPointer, 4), and(caller(), 0xffffffffffffffffffffffffffffffffffffffff))
switch eq(amount1, 0)
case 0 {
mstore(
add(freeMemoryPointer, 36),
add(div(mul(mul(reserve0, amount1), 100000), mul(sub(reserve1, amount1), sub(100000, fee))), 1)
)
}
default {
mstore(
add(freeMemoryPointer, 36),
add(div(mul(mul(reserve1, amount0), 100000), mul(sub(reserve0, amount0), sub(100000, fee))), 1)
)
}
if iszero(
and(
or(and(eq(mload(0), 1), gt(returndatasize(), 31)), iszero(returndatasize())),
call(gas(), token, 0, freeMemoryPointer, 68, 0, 32)
)
) {
revert(0, 0)
}
}
}
}
文件 5 的 23:ConveyorErrors.sol
pragma solidity =0.8.21;
error InsufficientWalletBalance(address account, uint256 balance, uint256 balanceNeeded);
error OrderDoesNotExist(bytes32 orderId);
error OrderQuantityIsZero();
error InsufficientOrderInputValue();
error IncongruentInputTokenInOrderGroup(address token, address expectedToken);
error TokenInIsTokenOut();
error IncongruentOutputTokenInOrderGroup(address token, address expectedToken);
error InsufficientOutputAmount(uint256 amountOut, uint256 expectedAmountOut);
error InsufficientInputAmount(uint256 amountIn, uint256 expectedAmountIn);
error InsufficientLiquidity();
error InsufficientAllowanceForOrderPlacement(address token, uint256 approvedQuantity, uint256 approvedQuantityNeeded);
error InsufficientAllowanceForOrderUpdate(address token, uint256 approvedQuantity, uint256 approvedQuantityNeeded);
error InvalidOrderGroupSequence();
error IncongruentFeeInInOrderGroup();
error IncongruentFeeOutInOrderGroup();
error IncongruentTaxedTokenInOrderGroup();
error IncongruentStoplossStatusInOrderGroup();
error IncongruentBuySellStatusInOrderGroup();
error NonEOAStoplossExecution();
error MsgSenderIsNotTxOrigin();
error MsgSenderIsNotLimitOrderRouter();
error MsgSenderIsNotLimitOrderExecutor();
error MsgSenderIsNotSandboxRouter();
error MsgSenderIsNotOwner();
error MsgSenderIsNotOrderOwner();
error MsgSenderIsNotOrderBook();
error MsgSenderIsNotLimitOrderBook();
error MsgSenderIsNotTempOwner();
error Reentrancy();
error ETHTransferFailed();
error InvalidAddress();
error UnauthorizedUniswapV3CallbackCaller();
error DuplicateOrderIdsInOrderGroup();
error InvalidCalldata();
error InsufficientMsgValue();
error UnauthorizedCaller();
error AmountInIsZero();
error SandboxCallFailed(uint256 callIndex);
error InvalidTransferAddressArray();
error AddressIsZero();
error IdenticalTokenAddresses();
error InvalidInputTokenForOrderPlacement();
error SandboxFillAmountNotSatisfied(bytes32 orderId, uint256 amountFilled, uint256 fillAmountRequired);
error OrderNotEligibleForRefresh(bytes32 orderId);
error SandboxAmountOutRequiredNotSatisfied(bytes32 orderId, uint256 amountOut, uint256 amountOutRequired);
error AmountOutRequiredIsZero(bytes32 orderId);
error FillAmountSpecifiedGreaterThanAmountRemaining(
uint256 fillAmountSpecified, uint256 amountInRemaining, bytes32 orderId
);
error ConveyorFeesNotPaid(uint256 expectedFees, uint256 feesPaid, uint256 unpaidFeesRemaining);
error InsufficientFillAmountSpecified(uint128 fillAmountSpecified, uint128 amountInRemaining);
error InsufficientExecutionCredit(uint256 msgValue, uint256 minExecutionCredit);
error WithdrawAmountExceedsExecutionCredit(uint256 amount, uint256 executionCredit);
error MsgValueIsNotCumulativeExecutionCredit(uint256 msgValue, uint256 cumulativeExecutionCredit);
error ExecutorNotCheckedIn();
error InvalidToAddressBits();
error V2SwapFailed();
error V3SwapFailed();
error CallFailed();
error InvalidReferral();
error InvalidReferralFee();
error AffiliateDoesNotExist();
error ReferrerDoesNotExist();
error ReferrerAlreadyInitialized();
文件 6 的 23:ConveyorMath.sol
pragma solidity =0.8.21;
import "../../lib/libraries/Uniswap/FullMath.sol";
library ConveyorMath {
uint128 private constant MAX_64x64 = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF;
uint256 private constant MAX_UINT64 = 0xFFFFFFFFFFFFFFFF;
int128 private constant MIN_64x64 = -0x80000000000000000000000000000000;
uint256 private constant MAX_128x128 = 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff;
function fromUInt256(uint256 x) internal pure returns (uint128) {
unchecked {
require(x <= MAX_UINT64);
return uint128(x << 64);
}
}
function toUInt64(uint128 x) internal pure returns (uint64) {
unchecked {
return uint64(x >> 64);
}
}
function fromUInt128(uint128 x) internal pure returns (uint256) {
unchecked {
require(x <= 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);
return uint256(x) << 128;
}
}
function from128x128(uint256 x) internal pure returns (uint128) {
unchecked {
uint256 answer = x >> 64;
require(answer >= 0x0 && answer <= MAX_64x64);
return uint128(answer);
}
}
function to128x128(uint128 x) internal pure returns (uint256) {
unchecked {
return uint256(x) << 64;
}
}
function add64x64(uint128 x, uint128 y) internal pure returns (uint128) {
unchecked {
uint256 answer = uint256(x) + y;
require(answer <= MAX_64x64);
return uint128(answer);
}
}
function sub(int128 x, int128 y) internal pure returns (int128) {
unchecked {
int256 result = int256(x) - y;
require(result >= MIN_64x64 && result <= type(int128).max);
return int128(result);
}
}
function add128x128(uint256 x, uint256 y) internal pure returns (uint256) {
uint256 answer = x + y;
return answer;
}
function add128x64(uint256 x, uint128 y) internal pure returns (uint256) {
uint256 answer = x + (uint256(y) << 64);
return answer;
}
function mul64x64(uint128 x, uint128 y) internal pure returns (uint128) {
unchecked {
uint256 answer = (uint256(x) * y) >> 64;
require(answer <= MAX_64x64);
return uint128(answer);
}
}
function mul128x64(uint256 x, uint128 y) internal pure returns (uint256) {
if (x == 0 || y == 0) {
return 0;
}
uint256 answer = (uint256(y) * x) >> 64;
return answer;
}
function mul64U(uint128 x, uint256 y) internal pure returns (uint256) {
unchecked {
if (y == 0 || x == 0) {
return 0;
}
uint256 lo = (uint256(x) * (y & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)) >> 64;
uint256 hi = uint256(x) * (y >> 128);
require(hi <= 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);
hi <<= 64;
require(hi <= MAX_128x128 - lo);
return hi + lo;
}
}
function mul128U(uint256 x, uint256 y) internal pure returns (uint256) {
if (y == 0 || x == 0) {
return 0;
}
return (x * y) >> 128;
}
function abs(int256 x) internal pure returns (int256) {
unchecked {
return x < 0 ? -x : x;
}
}
function div64x64(uint128 x, uint128 y) internal pure returns (uint128) {
unchecked {
require(y != 0);
uint256 answer = (uint256(x) << 64) / y;
require(answer <= 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);
return uint128(answer);
}
}
function div128x128(uint256 x, uint256 y) internal pure returns (uint256) {
unchecked {
require(y != 0);
uint256 xDec = x & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF;
uint256 xInt = x >> 128;
uint256 hi = xInt * (MAX_128x128 / y);
uint256 lo = (xDec * (MAX_128x128 / y)) >> 128;
require(hi <= MAX_128x128 - lo);
return hi + lo;
}
}
function divUU(uint256 x, uint256 y) internal pure returns (uint128) {
unchecked {
require(y != 0);
uint128 answer = divuu(x, y);
require(answer <= uint128(MAX_64x64), "overflow");
return answer;
}
}
function divuu(uint256 x, uint256 y) internal pure returns (uint128) {
unchecked {
require(y != 0);
uint256 answer;
if (x <= 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) {
answer = (x << 64) / y;
} else {
uint256 msb = 192;
uint256 xc = x >> 192;
if (xc >= 0x100000000) {
xc >>= 32;
msb += 32;
}
if (xc >= 0x10000) {
xc >>= 16;
msb += 16;
}
if (xc >= 0x100) {
xc >>= 8;
msb += 8;
}
if (xc >= 0x10) {
xc >>= 4;
msb += 4;
}
if (xc >= 0x4) {
xc >>= 2;
msb += 2;
}
if (xc >= 0x2) msb += 1;
answer = (x << (255 - msb)) / (((y - 1) >> (msb - 191)) + 1);
require(answer <= 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, "overflow in divuu");
uint256 hi = answer * (y >> 128);
uint256 lo = answer * (y & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);
uint256 xh = x >> 192;
uint256 xl = x << 64;
if (xl < lo) xh -= 1;
xl -= lo;
lo = hi << 128;
if (xl < lo) xh -= 1;
xl -= lo;
assert(xh == hi >> 128);
answer += xl / y;
}
require(answer <= 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, "overflow in divuu last");
return uint128(answer);
}
}
function fromX64ToX16(uint128 x) internal pure returns (uint32) {
uint16 decimals = uint16(uint64(x & 0xFFFFFFFFFFFFFFFF) >> 48);
uint16 integers = uint16(uint64(x >> 64) >> 48);
uint32 result = (uint32(integers) << 16) + decimals;
return result;
}
function exp_2(uint128 x) private pure returns (uint128) {
unchecked {
require(x < 0x400000000000000000);
uint256 answer = 0x80000000000000000000000000000000;
if (x & 0x8000000000000000 > 0) {
answer = (answer * 0x16A09E667F3BCC908B2FB1366EA957D3E) >> 128;
}
if (x & 0x4000000000000000 > 0) {
answer = (answer * 0x1306FE0A31B7152DE8D5A46305C85EDEC) >> 128;
}
if (x & 0x2000000000000000 > 0) {
answer = (answer * 0x1172B83C7D517ADCDF7C8C50EB14A791F) >> 128;
}
if (x & 0x1000000000000000 > 0) {
answer = (answer * 0x10B5586CF9890F6298B92B71842A98363) >> 128;
}
if (x & 0x800000000000000 > 0) {
answer = (answer * 0x1059B0D31585743AE7C548EB68CA417FD) >> 128;
}
if (x & 0x400000000000000 > 0) {
answer = (answer * 0x102C9A3E778060EE6F7CACA4F7A29BDE8) >> 128;
}
if (x & 0x200000000000000 > 0) {
answer = (answer * 0x10163DA9FB33356D84A66AE336DCDFA3F) >> 128;
}
if (x & 0x100000000000000 > 0) {
answer = (answer * 0x100B1AFA5ABCBED6129AB13EC11DC9543) >> 128;
}
if (x & 0x80000000000000 > 0) {
answer = (answer * 0x10058C86DA1C09EA1FF19D294CF2F679B) >> 128;
}
if (x & 0x40000000000000 > 0) {
answer = (answer * 0x1002C605E2E8CEC506D21BFC89A23A00F) >> 128;
}
if (x & 0x20000000000000 > 0) {
answer = (answer * 0x100162F3904051FA128BCA9C55C31E5DF) >> 128;
}
if (x & 0x10000000000000 > 0) {
answer = (answer * 0x1000B175EFFDC76BA38E31671CA939725) >> 128;
}
if (x & 0x8000000000000 > 0) {
answer = (answer * 0x100058BA01FB9F96D6CACD4B180917C3D) >> 128;
}
if (x & 0x4000000000000 > 0) {
answer = (answer * 0x10002C5CC37DA9491D0985C348C68E7B3) >> 128;
}
if (x & 0x2000000000000 > 0) {
answer = (answer * 0x1000162E525EE054754457D5995292026) >> 128;
}
if (x & 0x1000000000000 > 0) {
answer = (answer * 0x10000B17255775C040618BF4A4ADE83FC) >> 128;
}
if (x & 0x800000000000 > 0) {
answer = (answer * 0x1000058B91B5BC9AE2EED81E9B7D4CFAB) >> 128;
}
if (x & 0x400000000000 > 0) {
answer = (answer * 0x100002C5C89D5EC6CA4D7C8ACC017B7C9) >> 128;
}
if (x & 0x200000000000 > 0) {
answer = (answer * 0x10000162E43F4F831060E02D839A9D16D) >> 128;
}
if (x & 0x100000000000 > 0) {
answer = (answer * 0x100000B1721BCFC99D9F890EA06911763) >> 128;
}
if (x & 0x80000000000 > 0) {
answer = (answer * 0x10000058B90CF1E6D97F9CA14DBCC1628) >> 128;
}
if (x & 0x40000000000 > 0) {
answer = (answer * 0x1000002C5C863B73F016468F6BAC5CA2B) >> 128;
}
if (x & 0x20000000000 > 0) {
answer = (answer * 0x100000162E430E5A18F6119E3C02282A5) >> 128;
}
if (x & 0x10000000000 > 0) {
answer = (answer * 0x1000000B1721835514B86E6D96EFD1BFE) >> 128;
}
if (x & 0x8000000000 > 0) {
answer = (answer * 0x100000058B90C0B48C6BE5DF846C5B2EF) >> 128;
}
if (x & 0x4000000000 > 0) {
answer = (answer * 0x10000002C5C8601CC6B9E94213C72737A) >> 128;
}
if (x & 0x2000000000 > 0) {
answer = (answer * 0x1000000162E42FFF037DF38AA2B219F06) >> 128;
}
if (x & 0x1000000000 > 0) {
answer = (answer * 0x10000000B17217FBA9C739AA5819F44F9) >> 128;
}
if (x & 0x800000000 > 0) {
answer = (answer * 0x1000000058B90BFCDEE5ACD3C1CEDC823) >> 128;
}
if (x & 0x400000000 > 0) {
answer = (answer * 0x100000002C5C85FE31F35A6A30DA1BE50) >> 128;
}
if (x & 0x200000000 > 0) {
answer = (answer * 0x10000000162E42FF0999CE3541B9FFFCF) >> 128;
}
if (x & 0x100000000 > 0) {
answer = (answer * 0x100000000B17217F80F4EF5AADDA45554) >> 128;
}
if (x & 0x80000000 > 0) {
answer = (answer * 0x10000000058B90BFBF8479BD5A81B51AD) >> 128;
}
if (x & 0x40000000 > 0) {
answer = (answer * 0x1000000002C5C85FDF84BD62AE30A74CC) >> 128;
}
if (x & 0x20000000 > 0) {
answer = (answer * 0x100000000162E42FEFB2FED257559BDAA) >> 128;
}
if (x & 0x10000000 > 0) {
answer = (answer * 0x1000000000B17217F7D5A7716BBA4A9AE) >> 128;
}
if (x & 0x8000000 > 0) {
answer = (answer * 0x100000000058B90BFBE9DDBAC5E109CCE) >> 128;
}
if (x & 0x4000000 > 0) {
answer = (answer * 0x10000000002C5C85FDF4B15DE6F17EB0D) >> 128;
}
if (x & 0x2000000 > 0) {
answer = (answer * 0x1000000000162E42FEFA494F1478FDE05) >> 128;
}
if (x & 0x1000000 > 0) {
answer = (answer * 0x10000000000B17217F7D20CF927C8E94C) >> 128;
}
if (x & 0x800000 > 0) {
answer = (answer * 0x1000000000058B90BFBE8F71CB4E4B33D) >> 128;
}
if (x & 0x400000 > 0) {
answer = (answer * 0x100000000002C5C85FDF477B662B26945) >> 128;
}
if (x & 0x200000 > 0) {
answer = (answer * 0x10000000000162E42FEFA3AE53369388C) >> 128;
}
if (x & 0x100000 > 0) {
answer = (answer * 0x100000000000B17217F7D1D351A389D40) >> 128;
}
if (x & 0x80000 > 0) {
answer = (answer * 0x10000000000058B90BFBE8E8B2D3D4EDE) >> 128;
}
if (x & 0x40000 > 0) {
answer = (answer * 0x1000000000002C5C85FDF4741BEA6E77E) >> 128;
}
if (x & 0x20000 > 0) {
answer = (answer * 0x100000000000162E42FEFA39FE95583C2) >> 128;
}
if (x & 0x10000 > 0) {
answer = (answer * 0x1000000000000B17217F7D1CFB72B45E1) >> 128;
}
if (x & 0x8000 > 0) {
answer = (answer * 0x100000000000058B90BFBE8E7CC35C3F0) >> 128;
}
if (x & 0x4000 > 0) {
answer = (answer * 0x10000000000002C5C85FDF473E242EA38) >> 128;
}
if (x & 0x2000 > 0) {
answer = (answer * 0x1000000000000162E42FEFA39F02B772C) >> 128;
}
if (x & 0x1000 > 0) {
answer = (answer * 0x10000000000000B17217F7D1CF7D83C1A) >> 128;
}
if (x & 0x800 > 0) {
answer = (answer * 0x1000000000000058B90BFBE8E7BDCBE2E) >> 128;
}
if (x & 0x400 > 0) {
answer = (answer * 0x100000000000002C5C85FDF473DEA871F) >> 128;
}
if (x & 0x200 > 0) {
answer = (answer * 0x10000000000000162E42FEFA39EF44D91) >> 128;
}
if (x & 0x100 > 0) {
answer = (answer * 0x100000000000000B17217F7D1CF79E949) >> 128;
}
if (x & 0x80 > 0) {
answer = (answer * 0x10000000000000058B90BFBE8E7BCE544) >> 128;
}
if (x & 0x40 > 0) {
answer = (answer * 0x1000000000000002C5C85FDF473DE6ECA) >> 128;
}
if (x & 0x20 > 0) {
answer = (answer * 0x100000000000000162E42FEFA39EF366F) >> 128;
}
if (x & 0x10 > 0) {
answer = (answer * 0x1000000000000000B17217F7D1CF79AFA) >> 128;
}
if (x & 0x8 > 0) {
answer = (answer * 0x100000000000000058B90BFBE8E7BCD6D) >> 128;
}
if (x & 0x4 > 0) {
answer = (answer * 0x10000000000000002C5C85FDF473DE6B2) >> 128;
}
if (x & 0x2 > 0) {
answer = (answer * 0x1000000000000000162E42FEFA39EF358) >> 128;
}
if (x & 0x1 > 0) {
answer = (answer * 0x10000000000000000B17217F7D1CF79AB) >> 128;
}
answer >>= uint256(63 - (x >> 64));
require(answer <= uint256(MAX_64x64));
return uint128(uint256(answer));
}
}
function exp(uint128 x) internal pure returns (uint128) {
unchecked {
require(x < 0x400000000000000000, "Exponential overflow");
return exp_2(uint128((uint256(x) * 0x171547652B82FE1777D0FFDA0D23A7D12) >> 128));
}
}
function sqrtu(uint256 x) internal pure returns (uint128) {
unchecked {
if (x == 0) {
return 0;
} else {
uint256 xx = x;
uint256 r = 1;
if (xx >= 0x100000000000000000000000000000000) {
xx >>= 128;
r <<= 64;
}
if (xx >= 0x10000000000000000) {
xx >>= 64;
r <<= 32;
}
if (xx >= 0x100000000) {
xx >>= 32;
r <<= 16;
}
if (xx >= 0x10000) {
xx >>= 16;
r <<= 8;
}
if (xx >= 0x100) {
xx >>= 8;
r <<= 4;
}
if (xx >= 0x10) {
xx >>= 4;
r <<= 2;
}
if (xx >= 0x8) {
r <<= 1;
}
r = (r + x / r) >> 1;
r = (r + x / r) >> 1;
r = (r + x / r) >> 1;
r = (r + x / r) >> 1;
r = (r + x / r) >> 1;
r = (r + x / r) >> 1;
r = (r + x / r) >> 1;
uint256 r1 = x / r;
return uint128(r < r1 ? r : r1);
}
}
}
}
文件 7 的 23:ConveyorRouterV1.sol
pragma solidity =0.8.21;
import "./ConveyorErrors.sol";
import {IERC20} from "../lib/interfaces/token/IERC20.sol";
import {SafeERC20} from "../lib/libraries/token/SafeERC20.sol";
import {ConveyorMath} from "./lib/ConveyorMath.sol";
import {ConveyorSwapCallbacks} from "./callbacks/ConveyorSwapCallbacks.sol";
import {IConveyorRouterV1} from "./interfaces/IConveyorRouterV1.sol";
interface IConveyorMulticall {
function executeMulticall(
ConveyorRouterV1.SwapAggregatorMulticall calldata multicall
) external;
}
contract ConveyorRouterV1 is IConveyorRouterV1 {
using SafeERC20 for IERC20;
address public CONVEYOR_MULTICALL;
address public immutable WETH;
address owner;
address tempOwner;
uint128 private constant AFFILIATE_PERCENT = 5534023222112865000;
uint128 private constant REFERRAL_PERCENT = 5534023222112865000;
event Withdraw(address indexed receiver, uint256 amount);
modifier onlyOwner() {
if (msg.sender != owner) {
revert MsgSenderIsNotOwner();
}
_;
}
mapping(uint16 => address) public affiliates;
mapping(uint16 => address) public referrers;
mapping(address => uint16) public affiliateIndex;
mapping(address => uint16) public referrerIndex;
uint16 public affiliateNonce;
uint16 public referrerNonce;
constructor(address _weth) payable {
require(_weth != address(0), "WETH address is zero");
CONVEYOR_MULTICALL = address(new ConveyorMulticall());
WETH = _weth;
owner = tx.origin;
}
struct TokenToTokenSwapData {
address tokenIn;
address tokenOut;
uint112 amountIn;
uint112 amountOutMin;
uint16 affiliate;
uint16 referrer;
}
struct TokenToEthSwapData {
address tokenIn;
uint112 amountIn;
uint112 amountOutMin;
uint16 affiliate;
uint16 referrer;
}
struct EthToTokenSwapData {
address tokenOut;
uint112 amountOutMin;
uint112 protocolFee;
uint16 affiliate;
uint16 referrer;
}
struct SwapAggregatorMulticall {
address tokenInDestination;
Call[] calls;
}
struct Call {
address target;
bytes callData;
}
function swapExactTokenForToken(
TokenToTokenSwapData calldata swapData,
SwapAggregatorMulticall calldata genericMulticall
) public payable {
IERC20(swapData.tokenIn).safeTransferFrom(
msg.sender,
genericMulticall.tokenInDestination,
swapData.amountIn
);
uint256 balanceBefore = IERC20(swapData.tokenOut).balanceOf(msg.sender);
uint256 tokenOutAmountRequired = balanceBefore + swapData.amountOutMin;
IConveyorMulticall(CONVEYOR_MULTICALL).executeMulticall(
genericMulticall
);
uint256 balanceAfter = IERC20(swapData.tokenOut).balanceOf(msg.sender);
if (balanceAfter < tokenOutAmountRequired) {
revert InsufficientOutputAmount(
tokenOutAmountRequired - balanceAfter,
swapData.amountOutMin
);
}
if (swapData.affiliate & 0xFFFF != 0x0) {
address affiliate = affiliates[swapData.affiliate >> 0x1];
if (affiliate == address(0)) {
revert AffiliateDoesNotExist();
}
_safeTransferETH(
affiliate,
ConveyorMath.mul64U(AFFILIATE_PERCENT, msg.value)
);
}
if (swapData.referrer & 0xFFFF != 0x0) {
address referrer = referrers[swapData.referrer >> 0x1];
if (referrer == address(0)) {
revert ReferrerDoesNotExist();
}
_safeTransferETH(
referrer,
ConveyorMath.mul64U(REFERRAL_PERCENT, msg.value)
);
}
}
function swapExactEthForToken(
EthToTokenSwapData calldata swapData,
SwapAggregatorMulticall calldata swapAggregatorMulticall
) public payable {
if (swapData.protocolFee > msg.value) {
revert InsufficientMsgValue();
}
uint256 amountIn = msg.value - swapData.protocolFee;
_depositEth(amountIn, WETH);
IERC20(WETH).transfer(
swapAggregatorMulticall.tokenInDestination,
amountIn
);
uint256 balanceBefore = IERC20(swapData.tokenOut).balanceOf(msg.sender);
uint256 tokenOutAmountRequired = balanceBefore + swapData.amountOutMin;
IConveyorMulticall(CONVEYOR_MULTICALL).executeMulticall(
swapAggregatorMulticall
);
uint256 balanceAfter = IERC20(swapData.tokenOut).balanceOf(msg.sender);
if (balanceAfter < tokenOutAmountRequired) {
revert InsufficientOutputAmount(
tokenOutAmountRequired - balanceAfter,
swapData.amountOutMin
);
}
if (swapData.affiliate & 0xFFFF != 0x0) {
address affiliate = affiliates[swapData.affiliate >> 0x1];
if (affiliate == address(0)) {
revert AffiliateDoesNotExist();
}
_safeTransferETH(
affiliate,
ConveyorMath.mul64U(AFFILIATE_PERCENT, swapData.protocolFee)
);
}
if (swapData.referrer & 0xFFFF != 0x0) {
address referrer = referrers[swapData.referrer >> 0x1];
if (referrer == address(0)) {
revert ReferrerDoesNotExist();
}
_safeTransferETH(
referrer,
ConveyorMath.mul64U(REFERRAL_PERCENT, swapData.protocolFee)
);
}
}
function swapExactTokenForEth(
TokenToEthSwapData calldata swapData,
SwapAggregatorMulticall calldata swapAggregatorMulticall
) public payable {
if (swapAggregatorMulticall.tokenInDestination != address(0)) {
IERC20(swapData.tokenIn).safeTransferFrom(
msg.sender,
swapAggregatorMulticall.tokenInDestination,
swapData.amountIn
);
}
uint256 balanceBefore = msg.sender.balance;
uint256 amountOutRequired = balanceBefore + swapData.amountOutMin;
IConveyorMulticall(CONVEYOR_MULTICALL).executeMulticall(
swapAggregatorMulticall
);
uint256 balanceWeth = IERC20(WETH).balanceOf(address(this));
_withdrawEth(balanceWeth, WETH);
_safeTransferETH(msg.sender, balanceWeth);
if (msg.sender.balance < amountOutRequired) {
revert InsufficientOutputAmount(
amountOutRequired - msg.sender.balance,
swapData.amountOutMin
);
}
if (swapData.affiliate & 0xFFFF != 0x0) {
address affiliate = affiliates[swapData.affiliate >> 0x1];
if (affiliate == address(0)) {
revert AffiliateDoesNotExist();
}
_safeTransferETH(
affiliate,
ConveyorMath.mul64U(AFFILIATE_PERCENT, msg.value)
);
}
if (swapData.referrer & 0xFFFF != 0x0) {
address referrer = referrers[swapData.referrer >> 0x1];
if (referrer == address(0)) {
revert ReferrerDoesNotExist();
}
_safeTransferETH(
referrer,
ConveyorMath.mul64U(REFERRAL_PERCENT, msg.value)
);
}
}
function quoteSwapExactTokenForToken(
TokenToTokenSwapData calldata swapData,
SwapAggregatorMulticall calldata swapAggregatorMulticall
) external payable returns (uint256 gasConsumed) {
uint256 gasBefore;
assembly {
gasBefore := gas()
}
swapExactTokenForToken(swapData, swapAggregatorMulticall);
assembly {
gasConsumed := sub(gasBefore, gas())
}
}
function quoteSwapExactEthForToken(
EthToTokenSwapData calldata swapData,
SwapAggregatorMulticall calldata swapAggregatorMulticall
) external payable returns (uint256 gasConsumed) {
uint256 gasBefore;
assembly {
gasBefore := gas()
}
swapExactEthForToken(swapData, swapAggregatorMulticall);
assembly {
gasConsumed := sub(gasBefore, gas())
}
}
function quoteSwapExactTokenForEth(
TokenToEthSwapData calldata swapData,
SwapAggregatorMulticall calldata swapAggregatorMulticall
) external payable returns (uint256 gasConsumed) {
uint256 gasBefore;
assembly {
gasBefore := gas()
}
swapExactTokenForEth(swapData, swapAggregatorMulticall);
assembly {
gasConsumed := sub(gasBefore, gas())
}
}
function _safeTransferETH(address to, uint256 amount) internal {
bool success;
assembly {
success := call(gas(), to, amount, 0, 0, 0, 0)
}
if (!success) {
revert ETHTransferFailed();
}
}
function _withdrawEth(uint256 amount, address weth) internal {
assembly {
mstore(
0x0,
shl(224, 0x2e1a7d4d)
)
mstore(4, amount)
if iszero(
call(
gas() ,
weth ,
0 ,
0 ,
68 ,
0 ,
0
)
) {
revert("Native Token Withdraw failed", amount)
}
}
}
function _depositEth(uint256 amount, address weth) internal {
assembly {
mstore(0x0, shl(224, 0xd0e30db0))
if iszero(
call(
gas() ,
weth ,
amount ,
0 ,
0 ,
0 ,
0
)
) {
revert("Native token deposit failed", amount)
}
}
}
function withdraw() external onlyOwner {
_safeTransferETH(msg.sender, address(this).balance);
emit Withdraw(msg.sender, address(this).balance);
}
function confirmTransferOwnership() external {
if (msg.sender != tempOwner) {
revert UnauthorizedCaller();
}
tempOwner = address(0);
owner = msg.sender;
}
function transferOwnership(address newOwner) external onlyOwner {
if (newOwner == address(0)) {
revert InvalidAddress();
}
tempOwner = newOwner;
}
function upgradeMulticall(
bytes memory bytecode,
bytes32 salt
) external payable onlyOwner returns (address) {
assembly {
let addr := create2(
callvalue(),
add(bytecode, 0x20),
mload(bytecode),
salt
)
if iszero(extcodesize(addr)) {
revert(0, 0)
}
sstore(CONVEYOR_MULTICALL.slot, addr)
}
return CONVEYOR_MULTICALL;
}
function initializeAffiliate(address affiliateAddress) external onlyOwner {
uint16 tempAffiliateNonce = affiliateNonce;
affiliates[tempAffiliateNonce] = affiliateAddress;
affiliateIndex[affiliateAddress] = tempAffiliateNonce;
unchecked {
tempAffiliateNonce++;
require(
tempAffiliateNonce < type(uint16).max >> 0x1,
"Affiliate nonce overflow"
);
affiliateNonce = tempAffiliateNonce;
}
}
function initializeReferrer() external payable {
if (referrerIndex[msg.sender] != 0) {
revert ReferrerAlreadyInitialized();
}
uint16 tempReferrerNonce = referrerNonce;
referrers[tempReferrerNonce] = msg.sender;
referrerIndex[msg.sender] = uint16(tempReferrerNonce);
unchecked {
tempReferrerNonce++;
require(
tempReferrerNonce < type(uint16).max >> 0x1,
"Referrer nonce overflow"
);
referrerNonce = tempReferrerNonce;
}
}
receive() external payable {}
}
contract ConveyorMulticall is IConveyorMulticall, ConveyorSwapCallbacks {
constructor() {}
function executeMulticall(
ConveyorRouterV1.SwapAggregatorMulticall calldata multicall
) external {
for (uint256 i = 0; i < multicall.calls.length; ) {
address target = multicall.calls[i].target;
bytes calldata callData = multicall.calls[i].callData;
assembly ("memory-safe") {
let freeMemoryPointer := mload(0x40)
calldatacopy(
freeMemoryPointer,
callData.offset,
callData.length
)
if iszero(
call(
gas(),
target,
0,
freeMemoryPointer,
callData.length,
0,
0
)
) {
returndatacopy(0, 0, returndatasize())
revert(0, returndatasize())
}
}
unchecked {
++i;
}
}
}
}
文件 8 的 23:ConveyorSwapCallbacks.sol
pragma solidity =0.8.21;
import {PancakeV2Callback} from "./PancakeV2Callback.sol";
import {PancakeV3Callback} from "./PancakeV3Callback.sol";
import {UniswapV2Callback} from "./UniswapV2Callback.sol";
import {UniswapV3Callback} from "./UniswapV3Callback.sol";
import {ConvergenceXCallback} from "./ConvergenceXCallback.sol";
import {UniFiCallback} from "./UniFiCallback.sol";
import {VerseCallback} from "./VerseCallback.sol";
import {ApeSwapCallback} from "./ApeSwapCallback.sol";
import {LinkSwapCallback} from "./LinkSwapCallback.sol";
import {SakeSwapCallback} from "./SakeSwapCallback.sol";
import {DefiSwapCallback} from "./DefiSwapCallback.sol";
import {KyberSwapV3Callback} from "./KyberSwapV3Callback.sol";
import {AlgebraCallback} from "./AlgebraCallback.sol";
contract ConveyorSwapCallbacks is
PancakeV2Callback,
PancakeV3Callback,
UniswapV2Callback,
UniswapV3Callback,
ConvergenceXCallback,
UniFiCallback,
VerseCallback,
ApeSwapCallback,
LinkSwapCallback,
SakeSwapCallback,
DefiSwapCallback,
KyberSwapV3Callback,
AlgebraCallback
{}
文件 9 的 23:DefiSwapCallback.sol
pragma solidity =0.8.21;
contract DefiSwapCallback {
bytes4 private constant _UNISWAP_PAIR_RESERVES_CALL_SELECTOR = 0x0902f1ac;
function croDefiSwapCall(address, uint256 amount0, uint256 amount1, bytes calldata data) external {
assembly {
let freeMemoryPointer := mload(0x40)
let token := calldataload(data.offset)
let fee := calldataload(add(data.offset, 0x20))
mstore(freeMemoryPointer, _UNISWAP_PAIR_RESERVES_CALL_SELECTOR)
if iszero(staticcall(gas(), caller(), freeMemoryPointer, 0x4, freeMemoryPointer, 0x40)) {
revert(0, 0)
}
if iszero(eq(returndatasize(), 0x60)) {
mstore(0, 0x85cd58dc00000000000000000000000000000000000000000000000000000000)
revert(0, 4)
}
let reserve0 := mload(freeMemoryPointer)
let reserve1 := mload(add(freeMemoryPointer, 0x20))
mstore(freeMemoryPointer, 0xa9059cbb00000000000000000000000000000000000000000000000000000000)
mstore(add(freeMemoryPointer, 4), and(caller(), 0xffffffffffffffffffffffffffffffffffffffff))
switch eq(amount1, 0)
case 0 {
mstore(
add(freeMemoryPointer, 36),
add(div(mul(mul(reserve0, amount1), 100000), mul(sub(reserve1, amount1), sub(100000, fee))), 1)
)
}
default {
mstore(
add(freeMemoryPointer, 36),
add(div(mul(mul(reserve1, amount0), 100000), mul(sub(reserve0, amount0), sub(100000, fee))), 1)
)
}
if iszero(
and(
or(and(eq(mload(0), 1), gt(returndatasize(), 31)), iszero(returndatasize())),
call(gas(), token, 0, freeMemoryPointer, 68, 0, 32)
)
) {
revert(0, 0)
}
}
}
}
文件 10 的 23:FullMath.sol
pragma solidity ^0.8.0;
library FullMath {
function mulDiv(
uint256 a,
uint256 b,
uint256 denominator
) internal pure returns (uint256 result) {
unchecked {
uint256 prod0;
uint256 prod1;
assembly {
let mm := mulmod(a, b, not(0))
prod0 := mul(a, b)
prod1 := sub(sub(mm, prod0), lt(mm, prod0))
}
if (prod1 == 0) {
require(denominator > 0);
assembly {
result := div(prod0, denominator)
}
return result;
}
require(denominator > prod1);
uint256 remainder;
assembly {
remainder := mulmod(a, b, denominator)
}
assembly {
prod1 := sub(prod1, gt(remainder, prod0))
prod0 := sub(prod0, remainder)
}
uint256 twos = (0 - denominator) & denominator;
assembly {
denominator := div(denominator, twos)
}
assembly {
prod0 := div(prod0, twos)
}
assembly {
twos := add(div(sub(0, twos), twos), 1)
}
prod0 |= prod1 * twos;
uint256 inv = (3 * denominator) ^ 2;
inv *= 2 - denominator * inv;
inv *= 2 - denominator * inv;
inv *= 2 - denominator * inv;
inv *= 2 - denominator * inv;
inv *= 2 - denominator * inv;
inv *= 2 - denominator * inv;
result = prod0 * inv;
return result;
}
}
function mulDivRoundingUp(
uint256 a,
uint256 b,
uint256 denominator
) internal pure returns (uint256 result) {
unchecked {
result = mulDiv(a, b, denominator);
if (mulmod(a, b, denominator) > 0) {
require(result < type(uint256).max);
result++;
}
}
}
}
文件 11 的 23:IConveyorRouterV1.sol
pragma solidity =0.8.21;
import "../ConveyorRouterV1.sol";
interface IConveyorRouterV1 {
function swapExactTokenForToken(
ConveyorRouterV1.TokenToTokenSwapData calldata swapData,
ConveyorRouterV1.SwapAggregatorMulticall calldata genericMulticall
) external payable;
function swapExactEthForToken(
ConveyorRouterV1.EthToTokenSwapData calldata swapData,
ConveyorRouterV1.SwapAggregatorMulticall calldata swapAggregatorMulticall
) external payable;
function swapExactTokenForEth(
ConveyorRouterV1.TokenToEthSwapData calldata swapData,
ConveyorRouterV1.SwapAggregatorMulticall calldata swapAggregatorMulticall
) external payable;
function initializeAffiliate(address affiliateAddress) external;
function initializeReferrer() external payable;
function upgradeMulticall(bytes memory bytecode, bytes32 salt) external payable returns (address);
function quoteSwapExactTokenForToken(
ConveyorRouterV1.TokenToTokenSwapData calldata swapData,
ConveyorRouterV1.SwapAggregatorMulticall calldata swapAggregatorMulticall
) external payable returns (uint256 gasConsumed);
function quoteSwapExactTokenForEth(
ConveyorRouterV1.TokenToEthSwapData calldata swapData,
ConveyorRouterV1.SwapAggregatorMulticall calldata swapAggregatorMulticall
) external payable returns (uint256 gasConsumed);
function quoteSwapExactEthForToken(
ConveyorRouterV1.EthToTokenSwapData calldata swapData,
ConveyorRouterV1.SwapAggregatorMulticall calldata swapAggregatorMulticall
) external payable returns (uint256 gasConsumed);
function withdraw() external;
function CONVEYOR_MULTICALL() external view returns (address);
function affiliates(uint16) external view returns (address);
function referrers(uint16) external view returns (address);
}
文件 12 的 23:IERC20.sol
pragma solidity =0.8.21;
interface IERC20 {
event Transfer(address indexed from, address indexed to, uint256 value);
event Approval(
address indexed owner,
address indexed spender,
uint256 value
);
function totalSupply() external view returns (uint256);
function balanceOf(address account) external view returns (uint256);
function transfer(address to, uint256 amount) external returns (bool);
function allowance(address owner, address spender)
external
view
returns (uint256);
function approve(address spender, uint256 amount) external returns (bool);
function transferFrom(
address from,
address to,
uint256 amount
) external returns (bool);
function decimals() external view returns (uint8);
}
文件 13 的 23:KyberSwapV3Callback.sol
pragma solidity =0.8.21;
contract KyberSwapV3Callback {
function swapCallback(int256 amount0Delta, int256 amount1Delta, bytes calldata data) external {
assembly {
let freeMemoryPointer := mload(0x40)
let token := calldataload(data.offset)
mstore(freeMemoryPointer, 0xa9059cbb00000000000000000000000000000000000000000000000000000000)
mstore(add(freeMemoryPointer, 4), and(caller(), 0xffffffffffffffffffffffffffffffffffffffff))
switch slt(amount0Delta, 0)
case 0 { mstore(add(freeMemoryPointer, 36), amount0Delta) }
default { mstore(add(freeMemoryPointer, 36), amount1Delta) }
if iszero(
and(
or(and(eq(mload(0), 1), gt(returndatasize(), 31)), iszero(returndatasize())),
call(gas(), token, 0, freeMemoryPointer, 68, 0, 32)
)
) {
revert(0, 0)
}
}
}
}
文件 14 的 23:LinkSwapCallback.sol
pragma solidity =0.8.21;
contract LinkSwapCallback {
bytes4 private constant _UNISWAP_PAIR_RESERVES_CALL_SELECTOR = 0x0902f1ac;
function linkswapCall(address, uint256 amount0, uint256 amount1, bytes calldata data) external {
assembly {
let freeMemoryPointer := mload(0x40)
let token := calldataload(data.offset)
let fee := calldataload(add(data.offset, 0x20))
mstore(freeMemoryPointer, _UNISWAP_PAIR_RESERVES_CALL_SELECTOR)
if iszero(staticcall(gas(), caller(), freeMemoryPointer, 0x4, freeMemoryPointer, 0x40)) {
revert(0, 0)
}
if iszero(eq(returndatasize(), 0x60)) {
mstore(0, 0x85cd58dc00000000000000000000000000000000000000000000000000000000)
revert(0, 4)
}
let reserve0 := mload(freeMemoryPointer)
let reserve1 := mload(add(freeMemoryPointer, 0x20))
mstore(freeMemoryPointer, 0xa9059cbb00000000000000000000000000000000000000000000000000000000)
mstore(add(freeMemoryPointer, 4), and(caller(), 0xffffffffffffffffffffffffffffffffffffffff))
switch eq(amount1, 0)
case 0 {
mstore(
add(freeMemoryPointer, 36),
add(div(mul(mul(reserve0, amount1), 100000), mul(sub(reserve1, amount1), sub(100000, fee))), 1)
)
}
default {
mstore(
add(freeMemoryPointer, 36),
add(div(mul(mul(reserve1, amount0), 100000), mul(sub(reserve0, amount0), sub(100000, fee))), 1)
)
}
if iszero(
and(
or(and(eq(mload(0), 1), gt(returndatasize(), 31)), iszero(returndatasize())),
call(gas(), token, 0, freeMemoryPointer, 68, 0, 32)
)
) {
revert(0, 0)
}
}
}
}
文件 15 的 23:PancakeV2Callback.sol
pragma solidity =0.8.21;
contract PancakeV2Callback {
bytes4 private constant _UNISWAP_PAIR_RESERVES_CALL_SELECTOR = 0x0902f1ac;
function pancakeCall(address, uint256 amount0, uint256 amount1, bytes calldata data) external {
assembly {
let freeMemoryPointer := mload(0x40)
let token := calldataload(data.offset)
let fee := calldataload(add(data.offset, 0x20))
mstore(freeMemoryPointer, _UNISWAP_PAIR_RESERVES_CALL_SELECTOR)
if iszero(staticcall(gas(), caller(), freeMemoryPointer, 0x4, freeMemoryPointer, 0x40)) {
revert(0, 0)
}
if iszero(eq(returndatasize(), 0x60)) {
mstore(0, 0x85cd58dc00000000000000000000000000000000000000000000000000000000)
revert(0, 4)
}
let reserve0 := mload(freeMemoryPointer)
let reserve1 := mload(add(freeMemoryPointer, 0x20))
mstore(freeMemoryPointer, 0xa9059cbb00000000000000000000000000000000000000000000000000000000)
mstore(add(freeMemoryPointer, 4), and(caller(), 0xffffffffffffffffffffffffffffffffffffffff))
switch eq(amount1, 0)
case 0 {
mstore(
add(freeMemoryPointer, 36),
add(div(mul(mul(reserve0, amount1), 100000), mul(sub(reserve1, amount1), sub(100000, fee))), 1)
)
}
default {
mstore(
add(freeMemoryPointer, 36),
add(div(mul(mul(reserve1, amount0), 100000), mul(sub(reserve0, amount0), sub(100000, fee))), 1)
)
}
if iszero(
and(
or(and(eq(mload(0), 1), gt(returndatasize(), 31)), iszero(returndatasize())),
call(gas(), token, 0, freeMemoryPointer, 68, 0, 32)
)
) {
revert(0, 0)
}
}
}
}
文件 16 的 23:PancakeV3Callback.sol
pragma solidity =0.8.21;
contract PancakeV3Callback {
function pancakeV3SwapCallback(int256 amount0Delta, int256 amount1Delta, bytes calldata data) external {
assembly {
let freeMemoryPointer := mload(0x40)
let token := calldataload(data.offset)
mstore(freeMemoryPointer, 0xa9059cbb00000000000000000000000000000000000000000000000000000000)
mstore(add(freeMemoryPointer, 4), and(caller(), 0xffffffffffffffffffffffffffffffffffffffff))
switch slt(amount0Delta, 0)
case 0 { mstore(add(freeMemoryPointer, 36), amount0Delta) }
default { mstore(add(freeMemoryPointer, 36), amount1Delta) }
if iszero(
and(
or(and(eq(mload(0), 1), gt(returndatasize(), 31)), iszero(returndatasize())),
call(gas(), token, 0, freeMemoryPointer, 68, 0, 32)
)
) {
revert(0, 0)
}
}
}
}
文件 17 的 23:SafeERC20.sol
pragma solidity ^0.8.0;
import "../../interfaces/token/IERC20.sol";
import "../../interfaces/token/draft-IERC20Permit.sol";
import "../../utils/Address.sol";
library SafeERC20 {
using Address for address;
function safeTransfer(
IERC20 token,
address to,
uint256 value
) internal {
_callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));
}
function safeTransferFrom(
IERC20 token,
address from,
address to,
uint256 value
) internal {
_callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));
}
function safeApprove(
IERC20 token,
address spender,
uint256 value
) internal {
require(
(value == 0) || (token.allowance(address(this), spender) == 0),
"SafeERC20: approve from non-zero to non-zero allowance"
);
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));
}
function safeIncreaseAllowance(
IERC20 token,
address spender,
uint256 value
) internal {
uint256 newAllowance = token.allowance(address(this), spender) + value;
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
}
function safeDecreaseAllowance(
IERC20 token,
address spender,
uint256 value
) internal {
unchecked {
uint256 oldAllowance = token.allowance(address(this), spender);
require(oldAllowance >= value, "SafeERC20: decreased allowance below zero");
uint256 newAllowance = oldAllowance - value;
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
}
}
function safePermit(
IERC20Permit token,
address owner,
address spender,
uint256 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) internal {
uint256 nonceBefore = token.nonces(owner);
token.permit(owner, spender, value, deadline, v, r, s);
uint256 nonceAfter = token.nonces(owner);
require(nonceAfter == nonceBefore + 1, "SafeERC20: permit did not succeed");
}
function _callOptionalReturn(IERC20 token, bytes memory data) private {
bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed");
if (returndata.length > 0) {
require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed");
}
}
}
文件 18 的 23:SakeSwapCallback.sol
pragma solidity =0.8.21;
contract SakeSwapCallback {
bytes4 private constant _UNISWAP_PAIR_RESERVES_CALL_SELECTOR = 0x0902f1ac;
function SakeSwapCall(address, uint256 amount0, uint256 amount1, bytes calldata data) external {
assembly {
let freeMemoryPointer := mload(0x40)
let token := calldataload(data.offset)
let fee := calldataload(add(data.offset, 0x20))
mstore(freeMemoryPointer, _UNISWAP_PAIR_RESERVES_CALL_SELECTOR)
if iszero(staticcall(gas(), caller(), freeMemoryPointer, 0x4, freeMemoryPointer, 0x40)) {
revert(0, 0)
}
if iszero(eq(returndatasize(), 0x60)) {
mstore(0, 0x85cd58dc00000000000000000000000000000000000000000000000000000000)
revert(0, 4)
}
let reserve0 := mload(freeMemoryPointer)
let reserve1 := mload(add(freeMemoryPointer, 0x20))
mstore(freeMemoryPointer, 0xa9059cbb00000000000000000000000000000000000000000000000000000000)
mstore(add(freeMemoryPointer, 4), and(caller(), 0xffffffffffffffffffffffffffffffffffffffff))
switch eq(amount1, 0)
case 0 {
mstore(
add(freeMemoryPointer, 36),
add(div(mul(mul(reserve0, amount1), 100000), mul(sub(reserve1, amount1), sub(100000, fee))), 1)
)
}
default {
mstore(
add(freeMemoryPointer, 36),
add(div(mul(mul(reserve1, amount0), 100000), mul(sub(reserve0, amount0), sub(100000, fee))), 1)
)
}
if iszero(
and(
or(and(eq(mload(0), 1), gt(returndatasize(), 31)), iszero(returndatasize())),
call(gas(), token, 0, freeMemoryPointer, 68, 0, 32)
)
) {
revert(0, 0)
}
}
}
}
文件 19 的 23:UniFiCallback.sol
pragma solidity =0.8.21;
contract UniFiCallback {
bytes4 private constant _UNISWAP_PAIR_RESERVES_CALL_SELECTOR = 0x0902f1ac;
function unifiCall(address, uint256 amount0, uint256 amount1, bytes calldata data) external {
assembly {
let freeMemoryPointer := mload(0x40)
let token := calldataload(data.offset)
let fee := calldataload(add(data.offset, 0x20))
mstore(freeMemoryPointer, _UNISWAP_PAIR_RESERVES_CALL_SELECTOR)
if iszero(staticcall(gas(), caller(), freeMemoryPointer, 0x4, freeMemoryPointer, 0x40)) {
revert(0, 0)
}
if iszero(eq(returndatasize(), 0x60)) {
mstore(0, 0x85cd58dc00000000000000000000000000000000000000000000000000000000)
revert(0, 4)
}
let reserve0 := mload(freeMemoryPointer)
let reserve1 := mload(add(freeMemoryPointer, 0x20))
mstore(freeMemoryPointer, 0xa9059cbb00000000000000000000000000000000000000000000000000000000)
mstore(add(freeMemoryPointer, 4), and(caller(), 0xffffffffffffffffffffffffffffffffffffffff))
switch eq(amount1, 0)
case 0 {
mstore(
add(freeMemoryPointer, 36),
add(div(mul(mul(reserve0, amount1), 100000), mul(sub(reserve1, amount1), sub(100000, fee))), 1)
)
}
default {
mstore(
add(freeMemoryPointer, 36),
add(div(mul(mul(reserve1, amount0), 100000), mul(sub(reserve0, amount0), sub(100000, fee))), 1)
)
}
if iszero(
and(
or(and(eq(mload(0), 1), gt(returndatasize(), 31)), iszero(returndatasize())),
call(gas(), token, 0, freeMemoryPointer, 68, 0, 32)
)
) {
revert(0, 0)
}
}
}
}
文件 20 的 23:UniswapV2Callback.sol
pragma solidity =0.8.21;
contract UniswapV2Callback {
bytes4 private constant _UNISWAP_PAIR_RESERVES_CALL_SELECTOR = 0x0902f1ac;
function uniswapV2Call(address, uint256 amount0, uint256 amount1, bytes calldata data) external {
assembly {
let freeMemoryPointer := mload(0x40)
let token := calldataload(data.offset)
let fee := calldataload(add(data.offset, 0x20))
mstore(freeMemoryPointer, _UNISWAP_PAIR_RESERVES_CALL_SELECTOR)
if iszero(staticcall(gas(), caller(), freeMemoryPointer, 0x4, freeMemoryPointer, 0x40)) {
revert(0, 0)
}
if iszero(eq(returndatasize(), 0x60)) {
revert(0, 0)
}
let reserve0 := mload(freeMemoryPointer)
let reserve1 := mload(add(freeMemoryPointer, 0x20))
mstore(freeMemoryPointer, 0xa9059cbb00000000000000000000000000000000000000000000000000000000)
mstore(add(freeMemoryPointer, 4), and(caller(), 0xffffffffffffffffffffffffffffffffffffffff))
switch eq(amount1, 0)
case 0 {
mstore(
add(freeMemoryPointer, 36),
add(div(mul(mul(reserve0, amount1), 100000), mul(sub(reserve1, amount1), sub(100000, fee))), 1)
)
}
default {
mstore(
add(freeMemoryPointer, 36),
add(div(mul(mul(reserve1, amount0), 100000), mul(sub(reserve0, amount0), sub(100000, fee))), 1)
)
}
if iszero(
and(
or(and(eq(mload(0), 1), gt(returndatasize(), 31)), iszero(returndatasize())),
call(gas(), token, 0, freeMemoryPointer, 68, 0, 32)
)
) {
revert(0, 0)
}
}
}
}
文件 21 的 23:UniswapV3Callback.sol
pragma solidity =0.8.21;
contract UniswapV3Callback {
function uniswapV3SwapCallback(int256 amount0Delta, int256 amount1Delta, bytes calldata data) external {
assembly {
let freeMemoryPointer := mload(0x40)
let token := calldataload(data.offset)
mstore(freeMemoryPointer, 0xa9059cbb00000000000000000000000000000000000000000000000000000000)
mstore(add(freeMemoryPointer, 4), and(caller(), 0xffffffffffffffffffffffffffffffffffffffff))
switch slt(amount0Delta, 0)
case 0 { mstore(add(freeMemoryPointer, 36), amount0Delta) }
default { mstore(add(freeMemoryPointer, 36), amount1Delta) }
if iszero(
and(
or(and(eq(mload(0), 1), gt(returndatasize(), 31)), iszero(returndatasize())),
call(gas(), token, 0, freeMemoryPointer, 68, 0, 32)
)
) {
revert(0, 0)
}
}
}
}
文件 22 的 23:VerseCallback.sol
pragma solidity =0.8.21;
contract VerseCallback {
bytes4 private constant _UNISWAP_PAIR_RESERVES_CALL_SELECTOR = 0x0902f1ac;
function swapsCall(address, uint256 amount0, uint256 amount1, bytes calldata data) external {
assembly {
let freeMemoryPointer := mload(0x40)
let token := calldataload(data.offset)
let fee := calldataload(add(data.offset, 0x20))
mstore(freeMemoryPointer, _UNISWAP_PAIR_RESERVES_CALL_SELECTOR)
if iszero(staticcall(gas(), caller(), freeMemoryPointer, 0x4, freeMemoryPointer, 0x40)) {
revert(0, 0)
}
if iszero(eq(returndatasize(), 0x60)) {
mstore(0, 0x85cd58dc00000000000000000000000000000000000000000000000000000000)
revert(0, 4)
}
let reserve0 := mload(freeMemoryPointer)
let reserve1 := mload(add(freeMemoryPointer, 0x20))
mstore(freeMemoryPointer, 0xa9059cbb00000000000000000000000000000000000000000000000000000000)
mstore(add(freeMemoryPointer, 4), and(caller(), 0xffffffffffffffffffffffffffffffffffffffff))
switch eq(amount1, 0)
case 0 {
mstore(
add(freeMemoryPointer, 36),
add(div(mul(mul(reserve0, amount1), 100000), mul(sub(reserve1, amount1), sub(100000, fee))), 1)
)
}
default {
mstore(
add(freeMemoryPointer, 36),
add(div(mul(mul(reserve1, amount0), 100000), mul(sub(reserve0, amount0), sub(100000, fee))), 1)
)
}
if iszero(
and(
or(and(eq(mload(0), 1), gt(returndatasize(), 31)), iszero(returndatasize())),
call(gas(), token, 0, freeMemoryPointer, 68, 0, 32)
)
) {
revert(0, 0)
}
}
}
}
文件 23 的 23:draft-IERC20Permit.sol
pragma solidity ^0.8.0;
interface IERC20Permit {
function permit(
address owner,
address spender,
uint256 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) external;
function nonces(address owner) external view returns (uint256);
function DOMAIN_SEPARATOR() external view returns (bytes32);
}
{
"compilationTarget": {
"src/ConveyorRouterV1.sol": "ConveyorRouterV1"
},
"evmVersion": "paris",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs"
},
"optimizer": {
"enabled": true,
"runs": 200
},
"remappings": [
":create3-factory/=lib/create3-factory/",
":ds-test/=lib/ds-test/src/",
":forge-std/=lib/forge-std/src/",
":interfaces/=lib/interfaces/",
":libraries/=lib/libraries/",
":solmate/=lib/create3-factory/lib/solmate/src/",
":utils/=lib/utils/"
]
}
[{"inputs":[{"internalType":"address","name":"_weth","type":"address"}],"stateMutability":"payable","type":"constructor"},{"inputs":[],"name":"AffiliateDoesNotExist","type":"error"},{"inputs":[],"name":"ETHTransferFailed","type":"error"},{"inputs":[],"name":"InsufficientMsgValue","type":"error"},{"inputs":[{"internalType":"uint256","name":"amountOut","type":"uint256"},{"internalType":"uint256","name":"expectedAmountOut","type":"uint256"}],"name":"InsufficientOutputAmount","type":"error"},{"inputs":[],"name":"InvalidAddress","type":"error"},{"inputs":[],"name":"MsgSenderIsNotOwner","type":"error"},{"inputs":[],"name":"ReferrerAlreadyInitialized","type":"error"},{"inputs":[],"name":"ReferrerDoesNotExist","type":"error"},{"inputs":[],"name":"UnauthorizedCaller","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"receiver","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Withdraw","type":"event"},{"inputs":[],"name":"CONVEYOR_MULTICALL","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"WETH","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"affiliateIndex","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"affiliateNonce","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"","type":"uint16"}],"name":"affiliates","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"confirmTransferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"affiliateAddress","type":"address"}],"name":"initializeAffiliate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"initializeReferrer","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"tokenOut","type":"address"},{"internalType":"uint112","name":"amountOutMin","type":"uint112"},{"internalType":"uint112","name":"protocolFee","type":"uint112"},{"internalType":"uint16","name":"affiliate","type":"uint16"},{"internalType":"uint16","name":"referrer","type":"uint16"}],"internalType":"struct ConveyorRouterV1.EthToTokenSwapData","name":"swapData","type":"tuple"},{"components":[{"internalType":"address","name":"tokenInDestination","type":"address"},{"components":[{"internalType":"address","name":"target","type":"address"},{"internalType":"bytes","name":"callData","type":"bytes"}],"internalType":"struct ConveyorRouterV1.Call[]","name":"calls","type":"tuple[]"}],"internalType":"struct ConveyorRouterV1.SwapAggregatorMulticall","name":"swapAggregatorMulticall","type":"tuple"}],"name":"quoteSwapExactEthForToken","outputs":[{"internalType":"uint256","name":"gasConsumed","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"tokenIn","type":"address"},{"internalType":"uint112","name":"amountIn","type":"uint112"},{"internalType":"uint112","name":"amountOutMin","type":"uint112"},{"internalType":"uint16","name":"affiliate","type":"uint16"},{"internalType":"uint16","name":"referrer","type":"uint16"}],"internalType":"struct ConveyorRouterV1.TokenToEthSwapData","name":"swapData","type":"tuple"},{"components":[{"internalType":"address","name":"tokenInDestination","type":"address"},{"components":[{"internalType":"address","name":"target","type":"address"},{"internalType":"bytes","name":"callData","type":"bytes"}],"internalType":"struct ConveyorRouterV1.Call[]","name":"calls","type":"tuple[]"}],"internalType":"struct ConveyorRouterV1.SwapAggregatorMulticall","name":"swapAggregatorMulticall","type":"tuple"}],"name":"quoteSwapExactTokenForEth","outputs":[{"internalType":"uint256","name":"gasConsumed","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"tokenIn","type":"address"},{"internalType":"address","name":"tokenOut","type":"address"},{"internalType":"uint112","name":"amountIn","type":"uint112"},{"internalType":"uint112","name":"amountOutMin","type":"uint112"},{"internalType":"uint16","name":"affiliate","type":"uint16"},{"internalType":"uint16","name":"referrer","type":"uint16"}],"internalType":"struct ConveyorRouterV1.TokenToTokenSwapData","name":"swapData","type":"tuple"},{"components":[{"internalType":"address","name":"tokenInDestination","type":"address"},{"components":[{"internalType":"address","name":"target","type":"address"},{"internalType":"bytes","name":"callData","type":"bytes"}],"internalType":"struct ConveyorRouterV1.Call[]","name":"calls","type":"tuple[]"}],"internalType":"struct ConveyorRouterV1.SwapAggregatorMulticall","name":"swapAggregatorMulticall","type":"tuple"}],"name":"quoteSwapExactTokenForToken","outputs":[{"internalType":"uint256","name":"gasConsumed","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"referrerIndex","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"referrerNonce","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"","type":"uint16"}],"name":"referrers","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"tokenOut","type":"address"},{"internalType":"uint112","name":"amountOutMin","type":"uint112"},{"internalType":"uint112","name":"protocolFee","type":"uint112"},{"internalType":"uint16","name":"affiliate","type":"uint16"},{"internalType":"uint16","name":"referrer","type":"uint16"}],"internalType":"struct ConveyorRouterV1.EthToTokenSwapData","name":"swapData","type":"tuple"},{"components":[{"internalType":"address","name":"tokenInDestination","type":"address"},{"components":[{"internalType":"address","name":"target","type":"address"},{"internalType":"bytes","name":"callData","type":"bytes"}],"internalType":"struct ConveyorRouterV1.Call[]","name":"calls","type":"tuple[]"}],"internalType":"struct ConveyorRouterV1.SwapAggregatorMulticall","name":"swapAggregatorMulticall","type":"tuple"}],"name":"swapExactEthForToken","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"tokenIn","type":"address"},{"internalType":"uint112","name":"amountIn","type":"uint112"},{"internalType":"uint112","name":"amountOutMin","type":"uint112"},{"internalType":"uint16","name":"affiliate","type":"uint16"},{"internalType":"uint16","name":"referrer","type":"uint16"}],"internalType":"struct ConveyorRouterV1.TokenToEthSwapData","name":"swapData","type":"tuple"},{"components":[{"internalType":"address","name":"tokenInDestination","type":"address"},{"components":[{"internalType":"address","name":"target","type":"address"},{"internalType":"bytes","name":"callData","type":"bytes"}],"internalType":"struct ConveyorRouterV1.Call[]","name":"calls","type":"tuple[]"}],"internalType":"struct ConveyorRouterV1.SwapAggregatorMulticall","name":"swapAggregatorMulticall","type":"tuple"}],"name":"swapExactTokenForEth","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"tokenIn","type":"address"},{"internalType":"address","name":"tokenOut","type":"address"},{"internalType":"uint112","name":"amountIn","type":"uint112"},{"internalType":"uint112","name":"amountOutMin","type":"uint112"},{"internalType":"uint16","name":"affiliate","type":"uint16"},{"internalType":"uint16","name":"referrer","type":"uint16"}],"internalType":"struct ConveyorRouterV1.TokenToTokenSwapData","name":"swapData","type":"tuple"},{"components":[{"internalType":"address","name":"tokenInDestination","type":"address"},{"components":[{"internalType":"address","name":"target","type":"address"},{"internalType":"bytes","name":"callData","type":"bytes"}],"internalType":"struct ConveyorRouterV1.Call[]","name":"calls","type":"tuple[]"}],"internalType":"struct ConveyorRouterV1.SwapAggregatorMulticall","name":"genericMulticall","type":"tuple"}],"name":"swapExactTokenForToken","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes","name":"bytecode","type":"bytes"},{"internalType":"bytes32","name":"salt","type":"bytes32"}],"name":"upgradeMulticall","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]