编译器
0.8.11+commit.d7f03943
文件 1 的 24: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 functionCall(target, data, "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");
require(isContract(target), "Address: call to non-contract");
(bool success, bytes memory returndata) = target.call{value: value}(data);
return verifyCallResult(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) {
require(isContract(target), "Address: static call to non-contract");
(bool success, bytes memory returndata) = target.staticcall(data);
return verifyCallResult(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) {
require(isContract(target), "Address: delegate call to non-contract");
(bool success, bytes memory returndata) = target.delegatecall(data);
return verifyCallResult(success, returndata, errorMessage);
}
function verifyCallResult(
bool success,
bytes memory returndata,
string memory errorMessage
) internal pure returns (bytes memory) {
if (success) {
return returndata;
} else {
if (returndata.length > 0) {
assembly {
let returndata_size := mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert(errorMessage);
}
}
}
}
文件 2 的 24:BentoAdapter.sol
pragma solidity 0.8.11;
import "../interfaces/IBentoBoxMinimal.sol";
import "../base/ImmutableState.sol";
abstract contract BentoAdapter is ImmutableState {
function _depositToBentoBox(
address token,
address from,
address to,
uint256 amount,
uint256 share,
uint256 value
) internal {
bentoBox.deposit{value: value}(token, from, to, amount, share);
}
function _transferFromBentoBox(
address token,
address from,
address to,
uint256 amount,
uint256 share,
bool unwrapBento
) internal {
if (unwrapBento) {
bentoBox.withdraw(token, from, to, amount, share);
} else {
if (amount > 0) {
share = bentoBox.toShare(token, amount, false);
}
bentoBox.transfer(token, from, to, share);
}
}
}
文件 3 的 24:IBentoBoxMinimal.sol
pragma solidity 0.8.11;
interface IBentoBoxMinimal {
function balanceOf(address, address) external view returns (uint256);
function toShare(
address token,
uint256 amount,
bool roundUp
) external view returns (uint256 share);
function toAmount(
address token,
uint256 share,
bool roundUp
) external view returns (uint256 amount);
function registerProtocol() external;
function deposit(
address token_,
address from,
address to,
uint256 amount,
uint256 share
) external payable returns (uint256 amountOut, uint256 shareOut);
function withdraw(
address token_,
address from,
address to,
uint256 amount,
uint256 share
) external returns (uint256 amountOut, uint256 shareOut);
function transfer(
address token,
address from,
address to,
uint256 share
) external;
function setMasterContractApproval(
address user,
address masterContract,
bool approved,
uint8 v,
bytes32 r,
bytes32 s
) external;
}
文件 4 的 24:IERC20.sol
pragma solidity ^0.8.0;
import "../token/ERC20/IERC20.sol";
文件 5 的 24:IImmutableState.sol
pragma solidity 0.8.11;
import "./IBentoBoxMinimal.sol";
import "./stargate/IStargateRouter.sol";
import "./stargate/IStargateWidget.sol";
interface IImmutableState {
function bentoBox() external view returns (IBentoBoxMinimal);
function stargateRouter() external view returns (IStargateRouter);
function stargateWidget() external view returns (IStargateWidget);
function factory() external view returns (address);
function pairCodeHash() external view returns (bytes32);
}
文件 6 的 24:IPool.sol
pragma solidity 0.8.11;
interface IPool {
function swap(bytes calldata data)
external
returns (uint256 finalAmountOut);
function flashSwap(bytes calldata data)
external
returns (uint256 finalAmountOut);
function mint(bytes calldata data) external returns (uint256 liquidity);
function burn(bytes calldata data)
external
returns (TokenAmount[] memory withdrawnAmounts);
function burnSingle(bytes calldata data)
external
returns (uint256 amountOut);
function poolIdentifier() external pure returns (bytes32);
function getAssets() external view returns (address[] memory);
function getAmountOut(bytes calldata data)
external
view
returns (uint256 finalAmountOut);
function getAmountIn(bytes calldata data)
external
view
returns (uint256 finalAmountIn);
event Swap(
address indexed recipient,
address indexed tokenIn,
address indexed tokenOut,
uint256 amountIn,
uint256 amountOut
);
struct TokenAmount {
address token;
uint256 amount;
}
}
文件 7 的 24:IStargateAdapter.sol
pragma solidity 0.8.11;
import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import "../../base/ImmutableState.sol";
import "../ISushiXSwap.sol";
import "./IStargateReceiver.sol";
import "./IStargateWidget.sol";
interface IStargateAdapter {}
文件 8 的 24:IStargateReceiver.sol
pragma solidity 0.8.11;
interface IStargateReceiver {
function sgReceive(
uint16 _chainId,
bytes memory _srcAddress,
uint256 _nonce,
address _token,
uint256 amountLD,
bytes memory payload
) external;
}
文件 9 的 24:IStargateRouter.sol
pragma solidity 0.8.11;
interface IStargateRouter {
struct lzTxObj {
uint256 dstGasForCall;
uint256 dstNativeAmount;
bytes dstNativeAddr;
}
function swap(
uint16 _dstChainId,
uint256 _srcPoolId,
uint256 _dstPoolId,
address payable _refundAddress,
uint256 _amountLD,
uint256 _minAmountLD,
lzTxObj memory _lzTxParams,
bytes calldata _to,
bytes calldata _payload
) external payable;
function quoteLayerZeroFee(
uint16 _dstChainId,
uint8 _functionType,
bytes calldata _toAddress,
bytes calldata _transferAndCallPayload,
lzTxObj memory _lzTxParams
) external view returns (uint256, uint256);
}
文件 10 的 24:IStargateWidget.sol
pragma solidity 0.8.11;
interface IStargateWidget {
function partnerSwap(bytes2 _partnerId) external;
}
文件 11 的 24:ISushiXSwap.sol
pragma solidity 0.8.11;
import "../adapters/BentoAdapter.sol";
import "../adapters/TokenAdapter.sol";
import "../adapters/SushiLegacyAdapter.sol";
import "../adapters/TridentSwapAdapter.sol";
import "../adapters/StargateAdapter.sol";
interface ISushiXSwap {
function cook(
uint8[] memory actions,
uint256[] memory values,
bytes[] memory datas
) external payable;
}
文件 12 的 24:ITridentRouter.sol
pragma solidity 0.8.11;
import "./IPool.sol";
import "../IBentoBoxMinimal.sol";
import "@openzeppelin/contracts/interfaces/IERC20.sol";
interface ITridentRouter {
struct Path {
address pool;
bytes data;
}
struct ExactInputSingleParams {
uint256 amountIn;
uint256 amountOutMinimum;
address pool;
address tokenIn;
bytes data;
}
struct ExactInputParams {
address tokenIn;
uint256 amountIn;
uint256 amountOutMinimum;
Path[] path;
}
struct TokenInput {
address token;
bool native;
uint256 amount;
}
struct InitialPath {
address tokenIn;
address pool;
bool native;
uint256 amount;
bytes data;
}
struct PercentagePath {
address tokenIn;
address pool;
uint64 balancePercentage;
bytes data;
}
struct Output {
address token;
address to;
bool unwrapBento;
uint256 minAmount;
}
struct ComplexPathParams {
InitialPath[] initialPath;
PercentagePath[] percentagePath;
Output[] output;
}
}
文件 13 的 24:ITridentSwapAdapter.sol
pragma solidity 0.8.11;
import "./ITridentRouter.sol";
import "../../adapters/BentoAdapter.sol";
import "../../adapters/TokenAdapter.sol";
import "../../base/ImmutableState.sol";
interface ITridentSwapAdapter {}
文件 14 的 24:IUniswapV2Pair.sol
pragma solidity >=0.5.0;
interface IUniswapV2Pair {
event Approval(address indexed owner, address indexed spender, uint value);
event Transfer(address indexed from, address indexed to, uint value);
function name() external pure returns (string memory);
function symbol() external pure returns (string memory);
function decimals() external pure returns (uint8);
function totalSupply() external view returns (uint);
function balanceOf(address owner) external view returns (uint);
function allowance(address owner, address spender) external view returns (uint);
function approve(address spender, uint value) external returns (bool);
function transfer(address to, uint value) external returns (bool);
function transferFrom(address from, address to, uint value) external returns (bool);
function DOMAIN_SEPARATOR() external view returns (bytes32);
function PERMIT_TYPEHASH() external pure returns (bytes32);
function nonces(address owner) external view returns (uint);
function permit(address owner, address spender, uint value, uint deadline, uint8 v, bytes32 r, bytes32 s) external;
event Mint(address indexed sender, uint amount0, uint amount1);
event Burn(address indexed sender, uint amount0, uint amount1, address indexed to);
event Swap(
address indexed sender,
uint amount0In,
uint amount1In,
uint amount0Out,
uint amount1Out,
address indexed to
);
event Sync(uint112 reserve0, uint112 reserve1);
function MINIMUM_LIQUIDITY() external pure returns (uint);
function factory() external view returns (address);
function token0() external view returns (address);
function token1() external view returns (address);
function getReserves() external view returns (uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast);
function price0CumulativeLast() external view returns (uint);
function price1CumulativeLast() external view returns (uint);
function kLast() external view returns (uint);
function mint(address to) external returns (uint liquidity);
function burn(address to) external returns (uint amount0, uint amount1);
function swap(uint amount0Out, uint amount1Out, address to, bytes calldata data) external;
function skim(address to) external;
function sync() external;
function initialize(address, address) external;
}
文件 15 的 24:IWETH.sol
pragma solidity 0.8.11;
interface IWETH {
function deposit() external payable;
function transfer(address to, uint256 value) external returns (bool);
function withdraw(uint256) external;
}
文件 16 的 24:ImmutableState.sol
pragma solidity 0.8.11;
import "../interfaces/IImmutableState.sol";
abstract contract ImmutableState is IImmutableState {
IBentoBoxMinimal public immutable override bentoBox;
IStargateRouter public immutable override stargateRouter;
IStargateWidget public immutable override stargateWidget;
address public immutable override factory;
bytes32 public immutable override pairCodeHash;
constructor(
IBentoBoxMinimal _bentoBox,
IStargateRouter _stargateRouter,
address _factory,
bytes32 _pairCodeHash,
IStargateWidget _stargateWidget
) {
bentoBox = _bentoBox;
stargateRouter = _stargateRouter;
stargateWidget = _stargateWidget;
factory = _factory;
pairCodeHash = _pairCodeHash;
}
}
文件 17 的 24:SafeERC20.sol
pragma solidity ^0.8.0;
import "../IERC20.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 _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 的 24:SafeMath.sol
pragma solidity >=0.6.12;
library SafeMathUniswap {
function add(uint256 x, uint256 y) internal pure returns (uint256 z) {
require((z = x + y) >= x, "ds-math-add-overflow");
}
function sub(uint256 x, uint256 y) internal pure returns (uint256 z) {
require((z = x - y) <= x, "ds-math-sub-underflow");
}
function mul(uint256 x, uint256 y) internal pure returns (uint256 z) {
require(y == 0 || (z = x * y) / y == x, "ds-math-mul-overflow");
}
}
文件 19 的 24:StargateAdapter.sol
pragma solidity 0.8.11;
import "../interfaces/stargate/IStargateAdapter.sol";
abstract contract StargateAdapter is ImmutableState, IStargateReceiver {
using SafeERC20 for IERC20;
error NotStargateRouter();
event StargateSushiXSwapSrc(bytes32 indexed srcContext);
event StargateSushiXSwapDst(bytes32 indexed srcContext, bool failed);
struct StargateTeleportParams {
uint16 dstChainId;
address token;
uint256 srcPoolId;
uint256 dstPoolId;
uint256 amount;
uint256 amountMin;
uint256 dustAmount;
address receiver;
address to;
uint256 gas;
bytes32 srcContext;
}
function approveToStargateRouter(IERC20 token) external {
token.safeApprove(address(stargateRouter), type(uint256).max);
}
function _stargateTeleport(
StargateTeleportParams memory params,
uint8[] memory actions,
uint256[] memory values,
bytes[] memory datas
) internal {
bytes memory payload = abi.encode(params.to, actions, values, datas, params.srcContext);
stargateRouter.swap{value: address(this).balance}(
params.dstChainId,
params.srcPoolId,
params.dstPoolId,
payable(msg.sender),
params.amount != 0
? params.amount
: IERC20(params.token).balanceOf(address(this)),
params.amountMin,
IStargateRouter.lzTxObj(
params.gas,
params.dustAmount,
abi.encodePacked(params.receiver)
),
abi.encodePacked(params.receiver),
payload
);
stargateWidget.partnerSwap(0x0001);
emit StargateSushiXSwapSrc(params.srcContext);
}
function getFee(
uint16 _dstChainId,
uint8 _functionType,
address _receiver,
uint256 _gas,
uint256 _dustAmount,
bytes memory _payload
) external view returns (uint256 a, uint256 b) {
(a, b) = stargateRouter.quoteLayerZeroFee(
_dstChainId,
_functionType,
abi.encodePacked(_receiver),
abi.encode(_payload),
IStargateRouter.lzTxObj(
_gas,
_dustAmount,
abi.encodePacked(_receiver)
)
);
}
function sgReceive(
uint16,
bytes memory,
uint256,
address _token,
uint256 amountLD,
bytes memory payload
) external override {
if (msg.sender != address(stargateRouter)) revert NotStargateRouter();
(
address to,
uint8[] memory actions,
uint256[] memory values,
bytes[] memory datas,
bytes32 srcContext
) = abi.decode(payload, (address, uint8[], uint256[], bytes[], bytes32));
uint256 limit = gasleft() - 200000;
bool failed;
try
ISushiXSwap(payable(address(this))).cook{gas: limit}(
actions,
values,
datas
)
{} catch (bytes memory) {
IERC20(_token).safeTransfer(to, amountLD);
failed = true;
}
if (address(this).balance > 0)
to.call{value: (address(this).balance)}("");
emit StargateSushiXSwapDst(srcContext, failed);
}
}
文件 20 的 24:SushiLegacyAdapter.sol
pragma solidity 0.8.11;
import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import "../libraries/UniswapV2Library.sol";
import "../base/ImmutableState.sol";
abstract contract SushiLegacyAdapter is ImmutableState {
using SafeERC20 for IERC20;
function _swapExactTokensForTokens(
uint256 amountIn,
uint256 amountOutMin,
address[] memory path,
address to,
bool sendTokens
) internal returns (uint256 amountOut) {
uint256[] memory amounts = UniswapV2Library.getAmountsOut(
factory,
amountIn,
path,
pairCodeHash
);
amountOut = amounts[amounts.length - 1];
require(amountOut >= amountOutMin, "insufficient-amount-out");
if (sendTokens) {
IERC20(path[0]).safeTransfer(
UniswapV2Library.pairFor(
factory,
path[0],
path[1],
pairCodeHash
),
IERC20(path[0]).balanceOf(address(this))
);
}
_swap(amounts, path, to);
}
function _swap(
uint256[] memory amounts,
address[] memory path,
address _to
) internal virtual {
for (uint256 i; i < path.length - 1; i++) {
(address input, address output) = (path[i], path[i + 1]);
(address token0, ) = UniswapV2Library.sortTokens(input, output);
uint256 amountOut = amounts[i + 1];
(uint256 amount0Out, uint256 amount1Out) = input == token0
? (uint256(0), amountOut)
: (amountOut, uint256(0));
address to = i < path.length - 2
? UniswapV2Library.pairFor(
factory,
output,
path[i + 2],
pairCodeHash
)
: _to;
IUniswapV2Pair(
UniswapV2Library.pairFor(factory, input, output, pairCodeHash)
).swap(amount0Out, amount1Out, to, new bytes(0));
}
}
}
文件 21 的 24:SushiXSwap.sol
pragma solidity 0.8.11;
import "./interfaces/ISushiXSwap.sol";
contract SushiXSwap is
ISushiXSwap,
BentoAdapter,
TokenAdapter,
SushiLegacyAdapter,
TridentSwapAdapter,
StargateAdapter
{
constructor(
IBentoBoxMinimal _bentoBox,
IStargateRouter _stargateRouter,
address _factory,
bytes32 _pairCodeHash,
IStargateWidget _stargateWidget
) ImmutableState(_bentoBox, _stargateRouter, _factory, _pairCodeHash, _stargateWidget) {
_bentoBox.registerProtocol();
}
uint8 internal constant ACTION_MASTER_CONTRACT_APPROVAL = 0;
uint8 internal constant ACTION_SRC_DEPOSIT_TO_BENTOBOX = 1;
uint8 internal constant ACTION_SRC_TRANSFER_FROM_BENTOBOX = 2;
uint8 internal constant ACTION_DST_DEPOSIT_TO_BENTOBOX = 3;
uint8 internal constant ACTION_DST_WITHDRAW_TOKEN = 4;
uint8 internal constant ACTION_DST_WITHDRAW_OR_TRANSFER_FROM_BENTOBOX = 5;
uint8 internal constant ACTION_UNWRAP_AND_TRANSFER = 6;
uint8 internal constant ACTION_LEGACY_SWAP = 7;
uint8 internal constant ACTION_TRIDENT_SWAP = 8;
uint8 internal constant ACTION_TRIDENT_COMPLEX_PATH_SWAP = 9;
uint8 internal constant ACTION_STARGATE_TELEPORT = 10;
uint8 internal constant ACTION_SRC_TOKEN_TRANSFER = 11;
function cook(
uint8[] memory actions,
uint256[] memory values,
bytes[] memory datas
) public payable override {
uint256 actionLength = actions.length;
for (uint256 i; i < actionLength; i = _increment(i)) {
uint8 action = actions[i];
if (action == ACTION_MASTER_CONTRACT_APPROVAL) {
(
address user,
bool approved,
uint8 v,
bytes32 r,
bytes32 s
) = abi.decode(
datas[i],
(address, bool, uint8, bytes32, bytes32)
);
bentoBox.setMasterContractApproval(
user,
address(this),
approved,
v,
r,
s
);
} else if (action == ACTION_SRC_DEPOSIT_TO_BENTOBOX) {
(address token, address to, uint256 amount, uint256 share) = abi
.decode(datas[i], (address, address, uint256, uint256));
_depositToBentoBox(
token,
msg.sender,
to,
amount,
share,
values[i]
);
} else if (action == ACTION_SRC_TRANSFER_FROM_BENTOBOX) {
(
address token,
address to,
uint256 amount,
uint256 share,
bool unwrapBento
) = abi.decode(
datas[i],
(address, address, uint256, uint256, bool)
);
_transferFromBentoBox(
token,
msg.sender,
to,
amount,
share,
unwrapBento
);
} else if (action == ACTION_SRC_TOKEN_TRANSFER) {
(address token, address to, uint256 amount) = abi.decode(
datas[i],
(address, address, uint256)
);
_transferFromToken(IERC20(token), to, amount);
} else if (action == ACTION_DST_DEPOSIT_TO_BENTOBOX) {
(address token, address to, uint256 amount, uint256 share) = abi
.decode(datas[i], (address, address, uint256, uint256));
if (amount == 0) {
amount = IERC20(token).balanceOf(address(this));
}
_transferTokens(IERC20(token), address(bentoBox), amount);
_depositToBentoBox(
token,
address(bentoBox),
to,
amount,
share,
values[i]
);
} else if (action == ACTION_DST_WITHDRAW_TOKEN) {
(address token, address to, uint256 amount) = abi.decode(
datas[i],
(address, address, uint256)
);
if (amount == 0) {
if (token != address(0)) {
amount = IERC20(token).balanceOf(address(this));
} else {
amount = address(this).balance;
}
}
_transferTokens(IERC20(token), to, amount);
} else if (
action == ACTION_DST_WITHDRAW_OR_TRANSFER_FROM_BENTOBOX
) {
(
address token,
address to,
uint256 amount,
uint256 share,
bool unwrapBento
) = abi.decode(
datas[i],
(address, address, uint256, uint256, bool)
);
if (amount == 0 && share == 0) {
share = bentoBox.balanceOf(token, address(this));
}
_transferFromBentoBox(
token,
address(this),
to,
amount,
share,
unwrapBento
);
} else if (action == ACTION_UNWRAP_AND_TRANSFER) {
(address token, address to) = abi.decode(
datas[i],
(address, address)
);
_unwrapTransfer(token, to);
} else if (action == ACTION_LEGACY_SWAP) {
(
uint256 amountIn,
uint256 amountOutMin,
address[] memory path,
address to
) = abi.decode(
datas[i],
(uint256, uint256, address[], address)
);
bool sendTokens;
if (amountIn == 0) {
amountIn = IERC20(path[0]).balanceOf(address(this));
sendTokens = true;
}
_swapExactTokensForTokens(
amountIn,
amountOutMin,
path,
to,
sendTokens
);
} else if (action == ACTION_TRIDENT_SWAP) {
ExactInputParams memory params = abi.decode(
datas[i],
(ExactInputParams)
);
_exactInput(params);
} else if (action == ACTION_TRIDENT_COMPLEX_PATH_SWAP) {
ComplexPathParams memory params = abi.decode(
datas[i],
(ComplexPathParams)
);
_complexPath(params);
} else if (action == ACTION_STARGATE_TELEPORT) {
(
StargateTeleportParams memory params,
uint8[] memory actionsDST,
uint256[] memory valuesDST,
bytes[] memory datasDST
) = abi.decode(
datas[i],
(StargateTeleportParams, uint8[], uint256[], bytes[])
);
_stargateTeleport(params, actionsDST, valuesDST, datasDST);
}
}
}
receive() external payable {}
}
文件 22 的 24:TokenAdapter.sol
pragma solidity 0.8.11;
import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import "../interfaces/IWETH.sol";
abstract contract TokenAdapter {
using SafeERC20 for IERC20;
function _transferTokens(
IERC20 token,
address to,
uint256 amount
) internal {
if (address(token) != address(0)) {
token.safeTransfer(to, amount);
} else {
payable(to).transfer(amount);
}
}
function _transferFromToken(
IERC20 token,
address to,
uint256 amount
) internal {
token.safeTransferFrom(msg.sender, to, amount);
}
function _unwrapTransfer(address token, address to) internal {
IWETH(token).withdraw(IERC20(token).balanceOf(address(this)));
_transferTokens(IERC20(address(0)), to, address(this).balance);
}
}
文件 23 的 24:TridentSwapAdapter.sol
pragma solidity 0.8.11;
import "../interfaces/trident/ITridentSwapAdapter.sol";
abstract contract TridentSwapAdapter is
ITridentRouter,
ImmutableState,
BentoAdapter,
TokenAdapter
{
error TooLittleReceived();
function _exactInput(ExactInputParams memory params)
internal
returns (uint256 amountOut)
{
if (params.amountIn == 0) {
uint256 tokenBalance = IERC20(params.tokenIn).balanceOf(
address(this)
);
_transferTokens(
IERC20(params.tokenIn),
address(bentoBox),
tokenBalance
);
(, params.amountIn) = bentoBox.deposit(
params.tokenIn,
address(bentoBox),
params.path[0].pool,
tokenBalance,
0
);
}
uint256 n = params.path.length;
for (uint256 i = 0; i < n; i = _increment(i)) {
amountOut = IPool(params.path[i].pool).swap(params.path[i].data);
}
if (amountOut < params.amountOutMinimum) revert TooLittleReceived();
}
function _complexPath(ComplexPathParams memory params) internal {
uint256 n = params.initialPath.length;
for (uint256 i = 0; i < n; i = _increment(i)) {
bentoBox.transfer(
params.initialPath[i].tokenIn,
address(this),
params.initialPath[i].pool,
params.initialPath[i].amount
);
IPool(params.initialPath[i].pool).swap(params.initialPath[i].data);
}
n = params.percentagePath.length;
for (uint256 i = 0; i < n; i = _increment(i)) {
uint256 balanceShares = bentoBox.balanceOf(
params.percentagePath[i].tokenIn,
address(this)
);
uint256 transferShares = (balanceShares *
params.percentagePath[i].balancePercentage) / uint256(10)**8;
bentoBox.transfer(
params.percentagePath[i].tokenIn,
address(this),
params.percentagePath[i].pool,
transferShares
);
IPool(params.percentagePath[i].pool).swap(
params.percentagePath[i].data
);
}
n = params.output.length;
for (uint256 i = 0; i < n; i = _increment(i)) {
uint256 balanceShares = bentoBox.balanceOf(
params.output[i].token,
address(this)
);
if (balanceShares < params.output[i].minAmount)
revert TooLittleReceived();
if (params.output[i].unwrapBento) {
bentoBox.withdraw(
params.output[i].token,
address(this),
params.output[i].to,
0,
balanceShares
);
} else {
bentoBox.transfer(
params.output[i].token,
address(this),
params.output[i].to,
balanceShares
);
}
}
}
function _increment(uint256 i) internal pure returns (uint256) {
unchecked {
return i + 1;
}
}
}
文件 24 的 24:UniswapV2Library.sol
pragma solidity >=0.5.0;
import "@sushiswap/core/contracts/uniswapv2/interfaces/IUniswapV2Pair.sol";
import "./SafeMath.sol";
library UniswapV2Library {
using SafeMathUniswap for uint256;
function sortTokens(address tokenA, address tokenB)
internal
pure
returns (address token0, address token1)
{
require(tokenA != tokenB, "UniswapV2Library: IDENTICAL_ADDRESSES");
(token0, token1) = tokenA < tokenB
? (tokenA, tokenB)
: (tokenB, tokenA);
require(token0 != address(0), "UniswapV2Library: ZERO_ADDRESS");
}
function pairFor(
address factory,
address tokenA,
address tokenB,
bytes32 pairCodeHash
) internal pure returns (address pair) {
(address token0, address token1) = sortTokens(tokenA, tokenB);
pair = address(
uint160(
uint256(
keccak256(
abi.encodePacked(
hex"ff",
factory,
keccak256(abi.encodePacked(token0, token1)),
pairCodeHash
)
)
)
)
);
}
function getReserves(
address factory,
address tokenA,
address tokenB,
bytes32 pairCodeHash
) internal view returns (uint256 reserveA, uint256 reserveB) {
(address token0, ) = sortTokens(tokenA, tokenB);
(uint256 reserve0, uint256 reserve1, ) = IUniswapV2Pair(
pairFor(factory, tokenA, tokenB, pairCodeHash)
).getReserves();
(reserveA, reserveB) = tokenA == token0
? (reserve0, reserve1)
: (reserve1, reserve0);
}
function quote(
uint256 amountA,
uint256 reserveA,
uint256 reserveB
) internal pure returns (uint256 amountB) {
require(amountA > 0, "UniswapV2Library: INSUFFICIENT_AMOUNT");
require(
reserveA > 0 && reserveB > 0,
"UniswapV2Library: INSUFFICIENT_LIQUIDITY"
);
amountB = amountA.mul(reserveB) / reserveA;
}
function getAmountOut(
uint256 amountIn,
uint256 reserveIn,
uint256 reserveOut
) internal pure returns (uint256 amountOut) {
require(amountIn > 0, "UniswapV2Library: INSUFFICIENT_INPUT_AMOUNT");
require(
reserveIn > 0 && reserveOut > 0,
"UniswapV2Library: INSUFFICIENT_LIQUIDITY"
);
uint256 amountInWithFee = amountIn.mul(997);
uint256 numerator = amountInWithFee.mul(reserveOut);
uint256 denominator = reserveIn.mul(1000).add(amountInWithFee);
amountOut = numerator / denominator;
}
function getAmountIn(
uint256 amountOut,
uint256 reserveIn,
uint256 reserveOut
) internal pure returns (uint256 amountIn) {
require(amountOut > 0, "UniswapV2Library: INSUFFICIENT_OUTPUT_AMOUNT");
require(
reserveIn > 0 && reserveOut > 0,
"UniswapV2Library: INSUFFICIENT_LIQUIDITY"
);
uint256 numerator = reserveIn.mul(amountOut).mul(1000);
uint256 denominator = reserveOut.sub(amountOut).mul(997);
amountIn = (numerator / denominator).add(1);
}
function getAmountsOut(
address factory,
uint256 amountIn,
address[] memory path,
bytes32 pairCodeHash
) internal view returns (uint256[] memory amounts) {
require(path.length >= 2, "UniswapV2Library: INVALID_PATH");
amounts = new uint256[](path.length);
amounts[0] = amountIn;
for (uint256 i; i < path.length - 1; i++) {
(uint256 reserveIn, uint256 reserveOut) = getReserves(
factory,
path[i],
path[i + 1],
pairCodeHash
);
amounts[i + 1] = getAmountOut(amounts[i], reserveIn, reserveOut);
}
}
function getAmountsIn(
address factory,
uint256 amountOut,
address[] memory path,
bytes32 pairCodeHash
) internal view returns (uint256[] memory amounts) {
require(path.length >= 2, "UniswapV2Library: INVALID_PATH");
amounts = new uint256[](path.length);
amounts[amounts.length - 1] = amountOut;
for (uint256 i = path.length - 1; i > 0; i--) {
(uint256 reserveIn, uint256 reserveOut) = getReserves(
factory,
path[i - 1],
path[i],
pairCodeHash
);
amounts[i - 1] = getAmountIn(amounts[i], reserveIn, reserveOut);
}
}
}
{
"compilationTarget": {
"contracts/SushiXSwap.sol": "SushiXSwap"
},
"evmVersion": "london",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs",
"useLiteralContent": true
},
"optimizer": {
"enabled": true,
"runs": 999999
},
"remappings": []
}
[{"inputs":[{"internalType":"contract IBentoBoxMinimal","name":"_bentoBox","type":"address"},{"internalType":"contract IStargateRouter","name":"_stargateRouter","type":"address"},{"internalType":"address","name":"_factory","type":"address"},{"internalType":"bytes32","name":"_pairCodeHash","type":"bytes32"},{"internalType":"contract IStargateWidget","name":"_stargateWidget","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"NotStargateRouter","type":"error"},{"inputs":[],"name":"TooLittleReceived","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"srcContext","type":"bytes32"},{"indexed":false,"internalType":"bool","name":"failed","type":"bool"}],"name":"StargateSushiXSwapDst","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"srcContext","type":"bytes32"}],"name":"StargateSushiXSwapSrc","type":"event"},{"inputs":[{"internalType":"contract IERC20","name":"token","type":"address"}],"name":"approveToStargateRouter","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"bentoBox","outputs":[{"internalType":"contract IBentoBoxMinimal","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint8[]","name":"actions","type":"uint8[]"},{"internalType":"uint256[]","name":"values","type":"uint256[]"},{"internalType":"bytes[]","name":"datas","type":"bytes[]"}],"name":"cook","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"factory","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"_dstChainId","type":"uint16"},{"internalType":"uint8","name":"_functionType","type":"uint8"},{"internalType":"address","name":"_receiver","type":"address"},{"internalType":"uint256","name":"_gas","type":"uint256"},{"internalType":"uint256","name":"_dustAmount","type":"uint256"},{"internalType":"bytes","name":"_payload","type":"bytes"}],"name":"getFee","outputs":[{"internalType":"uint256","name":"a","type":"uint256"},{"internalType":"uint256","name":"b","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pairCodeHash","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"","type":"uint16"},{"internalType":"bytes","name":"","type":"bytes"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"address","name":"_token","type":"address"},{"internalType":"uint256","name":"amountLD","type":"uint256"},{"internalType":"bytes","name":"payload","type":"bytes"}],"name":"sgReceive","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"stargateRouter","outputs":[{"internalType":"contract IStargateRouter","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"stargateWidget","outputs":[{"internalType":"contract IStargateWidget","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"stateMutability":"payable","type":"receive"}]