Latest 25 from a total of 972 transactions
| Transaction Hash |
|
Block
|
From
|
To
|
|||||
|---|---|---|---|---|---|---|---|---|---|
| Swap Exact Eth F... | 410170634 | 43 days ago | IN | 0.00018547 ETH | 0.00000143 | ||||
| Swap Exact Eth F... | 410170390 | 43 days ago | IN | 0.00018745 ETH | 0.00000142 | ||||
| Swap Exact Eth F... | 409845366 | 44 days ago | IN | 0.00019482 ETH | 0.00000116 | ||||
| Swap Exact Eth F... | 409844227 | 44 days ago | IN | 0.00019282 ETH | 0.00000116 | ||||
| Swap Exact Eth F... | 409842745 | 44 days ago | IN | 0.00020282 ETH | 0.00000116 | ||||
| Swap Exact Eth F... | 409727486 | 45 days ago | IN | 0.00014282 ETH | 0.00000116 | ||||
| Swap Exact Eth F... | 409722214 | 45 days ago | IN | 0.00018282 ETH | 0.00000116 | ||||
| Swap Exact Eth F... | 409145493 | 46 days ago | IN | 0.00019282 ETH | 0.00000116 | ||||
| Swap Exact Eth F... | 409144978 | 46 days ago | IN | 0.00020282 ETH | 0.00000116 | ||||
| Swap Exact Eth F... | 408503039 | 48 days ago | IN | 0.00019958 ETH | 0.00001159 | ||||
| Swap Exact Eth F... | 407735515 | 50 days ago | IN | 0.00006782 ETH | 0.00000116 | ||||
| Swap Exact Eth F... | 407706542 | 50 days ago | IN | 0.00007282 ETH | 0.00000116 | ||||
| Swap Exact Eth F... | 407691591 | 50 days ago | IN | 0.00007348 ETH | 0.00000143 | ||||
| Swap Exact Eth F... | 407042604 | 52 days ago | IN | 0.00012783 ETH | 0.00000335 | ||||
| Swap Exact Eth F... | 407040647 | 52 days ago | IN | 0.00014081 ETH | 0.00000441 | ||||
| Swap Exact Eth F... | 407032522 | 52 days ago | IN | 0.00008277 ETH | 0.00000524 | ||||
| Swap Exact Eth F... | 406726152 | 53 days ago | IN | 0.00012282 ETH | 0.00000117 | ||||
| Swap Exact Eth F... | 405628227 | 56 days ago | IN | 0.00020273 ETH | 0.00000134 | ||||
| Swap Exact Eth F... | 405302999 | 57 days ago | IN | 0.00051635 ETH | 0.00000162 | ||||
| Swap Exact Eth F... | 405214056 | 58 days ago | IN | 0.00019282 ETH | 0.00000117 | ||||
| Swap Exact Eth F... | 404962269 | 58 days ago | IN | 0.00020282 ETH | 0.00000117 | ||||
| Swap Exact Eth F... | 404958272 | 58 days ago | IN | 0.00010552 ETH | 0.00000242 | ||||
| Swap Exact Eth F... | 404849065 | 59 days ago | IN | 0.00019282 ETH | 0.00000117 | ||||
| Swap Exact Eth F... | 404848083 | 59 days ago | IN | 0.00020309 ETH | 0.00000131 | ||||
| Swap Exact Eth F... | 404519344 | 60 days ago | IN | 0.00020282 ETH | 0.00000117 |
Latest 25 internal transactions (View All)
| Parent Transaction Hash | Block | From | To | |||
|---|---|---|---|---|---|---|
| 423429964 | 5 days ago | 0.1318615 ETH | ||||
| 423429964 | 5 days ago | 0.1318615 ETH | ||||
| 410170634 | 43 days ago | 0.000183 ETH | ||||
| 410170390 | 43 days ago | 0.000185 ETH | ||||
| 409845366 | 44 days ago | 0.000192 ETH | ||||
| 409844227 | 44 days ago | 0.00019 ETH | ||||
| 409842745 | 44 days ago | 0.0002 ETH | ||||
| 409727486 | 45 days ago | 0.00014 ETH | ||||
| 409722214 | 45 days ago | 0.00018 ETH | ||||
| 409145493 | 46 days ago | 0.00019 ETH | ||||
| 409144978 | 46 days ago | 0.0002 ETH | ||||
| 408503039 | 48 days ago | 0.000172 ETH | ||||
| 408243345 | 49 days ago | 1.70385972 ETH | ||||
| 408243345 | 49 days ago | 1.70385972 ETH | ||||
| 408243148 | 49 days ago | 1.63342552 ETH | ||||
| 408243148 | 49 days ago | 1.63342552 ETH | ||||
| 407735515 | 50 days ago | 0.000065 ETH | ||||
| 407706542 | 50 days ago | 0.00007 ETH | ||||
| 407691591 | 50 days ago | 0.00007 ETH | ||||
| 407042604 | 52 days ago | 0.00012 ETH | ||||
| 407040647 | 52 days ago | 0.00013 ETH | ||||
| 407032522 | 52 days ago | 0.00007 ETH | ||||
| 406726152 | 53 days ago | 0.00012 ETH | ||||
| 405628227 | 56 days ago | 0.0002 ETH | ||||
| 405302999 | 57 days ago | 0.000514 ETH |
Cross-Chain Transactions
Loading...
Loading
Contract Name:
ConveyorRouterV1
Compiler Version
v0.8.21+commit.d9974bed
Optimization Enabled:
Yes with 200 runs
Other Settings:
paris EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: BUSL-1.1
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;
}
/// @title ConveyorRouterV1
/// @author 0xKitsune, 0xOsiris, Conveyor Labs
/// @notice Multicall contract for token Swaps.
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;
/**
* @notice Event that is emitted when ETH is withdrawn from the contract
*
*/
event Withdraw(address indexed receiver, uint256 amount);
///@notice Modifier function to only allow the owner of the contract to call specific functions
///@dev Functions with onlyOwner: withdraw
modifier onlyOwner() {
if (msg.sender != owner) {
revert MsgSenderIsNotOwner();
}
_;
}
///@notice Mapping from uint16 to affiliate address.
mapping(uint16 => address) public affiliates;
///@notice Mapping from uint16 to referrer address.
mapping(uint16 => address) public referrers;
///@notice Mapping from affiliate address to affiliate index.
mapping(address => uint16) public affiliateIndex;
///@notice Mapping from referrer address to referrer index.
mapping(address => uint16) public referrerIndex;
///@notice Current Nonce for affiliate addresses.
uint16 public affiliateNonce;
///@notice Current Nonce for referrer addresses.
uint16 public referrerNonce;
///@dev Deploys the ConveyorMulticall contract.
///@param _weth Address of Wrapped Native Asset.
constructor(address _weth) payable {
require(_weth != address(0), "WETH address is zero");
CONVEYOR_MULTICALL = address(new ConveyorMulticall());
WETH = _weth;
owner = tx.origin;
}
///@notice Struct for token to token swap data.
struct TokenToTokenSwapData {
address tokenIn;
address tokenOut;
uint112 amountIn;
uint112 amountOutMin;
uint16 affiliate;
uint16 referrer;
}
///@notice Struct for token to ETH swap data.
struct TokenToEthSwapData {
address tokenIn;
uint112 amountIn;
uint112 amountOutMin;
uint16 affiliate;
uint16 referrer;
}
///@notice Struct for ETH to token swap data.
struct EthToTokenSwapData {
address tokenOut;
uint112 amountOutMin;
uint112 protocolFee;
uint16 affiliate;
uint16 referrer;
}
/// @notice Gas optimized Multicall struct
struct SwapAggregatorMulticall {
address tokenInDestination;
Call[] calls;
}
/// @notice Call struct for token Swaps.
/// @param target Address to call.
/// @param callData Data to call.
struct Call {
address target;
bytes callData;
}
/// @notice Swap tokens for tokens.
/// @param swapData The swap data for the transaction.
/// @param genericMulticall Multicall to be executed.
function swapExactTokenForToken(
TokenToTokenSwapData calldata swapData,
SwapAggregatorMulticall calldata genericMulticall
) public payable {
///@notice Transfer tokenIn from msg.sender to tokenInDestination address.
IERC20(swapData.tokenIn).safeTransferFrom(msg.sender, genericMulticall.tokenInDestination, swapData.amountIn);
///@notice Get tokenOut balance of msg.sender.
uint256 balanceBefore = IERC20(swapData.tokenOut).balanceOf(msg.sender);
///@notice Calculate tokenOut amount required.
uint256 tokenOutAmountRequired = balanceBefore + swapData.amountOutMin;
///@notice Execute Multicall.
IConveyorMulticall(CONVEYOR_MULTICALL).executeMulticall(genericMulticall);
uint256 balanceAfter = IERC20(swapData.tokenOut).balanceOf(msg.sender);
///@notice Check if tokenOut balance of msg.sender is sufficient.
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));
}
///@dev First bit of referrer is used to check if referrer exists
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));
}
}
/// @notice Swap ETH for tokens.
/// @param swapData The swap data for the transaction.
/// @param swapAggregatorMulticall Multicall to be executed.
function swapExactEthForToken(
EthToTokenSwapData calldata swapData,
SwapAggregatorMulticall calldata swapAggregatorMulticall
) public payable {
if (swapData.protocolFee > msg.value) {
revert InsufficientMsgValue();
}
///@notice Cache the amountIn to save gas.
uint256 amountIn = msg.value - swapData.protocolFee;
///@notice Deposit the msg.value-protocolFee into WETH.
_depositEth(amountIn, WETH);
///@notice Transfer WETH from WETH to tokenInDestination address.
IERC20(WETH).transfer(swapAggregatorMulticall.tokenInDestination, amountIn);
///@notice Get tokenOut balance of msg.sender.
uint256 balanceBefore = IERC20(swapData.tokenOut).balanceOf(msg.sender);
///@notice Calculate tokenOut amount required.
uint256 tokenOutAmountRequired = balanceBefore + swapData.amountOutMin;
///@notice Execute Multicall.
IConveyorMulticall(CONVEYOR_MULTICALL).executeMulticall(swapAggregatorMulticall);
///@notice Get tokenOut balance of msg.sender after multicall execution.
uint256 balanceAfter = IERC20(swapData.tokenOut).balanceOf(msg.sender);
///@notice Revert if tokenOut balance of msg.sender is insufficient.
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));
}
///@dev First bit of referrer is used to check if referrer exists
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));
}
}
/// @notice Swap tokens for ETH.
/// @param swapData The swap data for the transaction.
/// @param swapAggregatorMulticall Multicall to be executed.
function swapExactTokenForEth(
TokenToEthSwapData calldata swapData,
SwapAggregatorMulticall calldata swapAggregatorMulticall
) public payable {
///@dev Ignore if the tokenInDestination is address(0).
if (swapAggregatorMulticall.tokenInDestination != address(0)) {
///@notice Transfer tokenIn from msg.sender to tokenInDestination address.
IERC20(swapData.tokenIn).safeTransferFrom(
msg.sender, swapAggregatorMulticall.tokenInDestination, swapData.amountIn
);
}
///@notice Get ETH balance of msg.sender.
uint256 balanceBefore = msg.sender.balance;
///@notice Calculate amountOutRequired.
uint256 amountOutRequired = balanceBefore + swapData.amountOutMin;
///@notice Execute Multicall.
IConveyorMulticall(CONVEYOR_MULTICALL).executeMulticall(swapAggregatorMulticall);
///@notice Get WETH balance of this contract.
uint256 balanceWeth = IERC20(WETH).balanceOf(address(this));
///@notice Withdraw WETH from this contract.
_withdrawEth(balanceWeth, WETH);
///@notice Transfer ETH to msg.sender.
_safeTransferETH(msg.sender, balanceWeth);
///@notice Revert if Eth balance of the caller is insufficient.
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));
}
///@dev First bit of referrer is used to check if referrer exists
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));
}
}
/// @notice Quotes the amount of gas used for a optimized token to token swap.
/// @dev This function should be used off chain through a static call.
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())
}
}
/// @notice Quotes the amount of gas used for a ETH to token swap.
/// @dev This function should be used off chain through a static call.
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())
}
}
/// @notice Quotes the amount of gas used for a token to ETH swap.
/// @dev This function should be used off chain through a static call.
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())
}
}
///@notice Helper function to transfer ETH.
function _safeTransferETH(address to, uint256 amount) internal {
bool success;
/// @solidity memory-safe-assembly
assembly {
// Transfer the ETH and store if it succeeded or not.
success := call(gas(), to, amount, 0, 0, 0, 0)
}
if (!success) {
revert ETHTransferFailed();
}
}
/// @notice Helper function to Withdraw ETH from WETH.
function _withdrawEth(uint256 amount, address weth) internal {
/// @solidity memory-safe-assembly
assembly {
mstore(0x0, shl(224, 0x2e1a7d4d) /* keccak256("withdraw(uint256)") */ )
mstore(4, amount)
if iszero(
call(
gas(), /* gas */
weth, /* to */
0, /* value */
0, /* in */
68, /* in size */
0, /* out */
0 /* out size */
)
) { revert("Native Token Withdraw failed", amount) }
}
}
/// @notice Helper function to Deposit ETH into WETH.
function _depositEth(uint256 amount, address weth) internal {
/// @solidity memory-safe-assembly
assembly {
mstore(0x0, shl(224, 0xd0e30db0)) /* keccak256("deposit()") */
if iszero(
call(
gas(), /* gas */
weth, /* to */
amount, /* value */
0, /* in */
0, /* in size */
0, /* out */
0 /* out size */
)
) { revert("Native token deposit failed", amount) }
}
}
/// @notice Withdraw ETH from this contract.
function withdraw() external onlyOwner {
_safeTransferETH(msg.sender, address(this).balance);
emit Withdraw(msg.sender, address(this).balance);
}
///@notice Function to confirm ownership transfer of the contract.
function confirmTransferOwnership() external {
if (msg.sender != tempOwner) {
revert UnauthorizedCaller();
}
///@notice Cleanup tempOwner storage.
tempOwner = address(0);
owner = msg.sender;
}
///@notice Function to transfer ownership of the contract.
function transferOwnership(address newOwner) external onlyOwner {
if (newOwner == address(0)) {
revert InvalidAddress();
}
tempOwner = newOwner;
}
///@notice Function to upgrade the ConveyorMulticall contract.
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;
}
///@notice Function to set affiliate address.
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;
}
}
///@notice Function to set referrer mapping.
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;
}
}
/// @notice Fallback receiver function.
receive() external payable {}
}
/// @title ConveyorMulticall
/// @author 0xOsiris, 0xKitsune, Conveyor Labs
/// @notice Optimized multicall execution contract.
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;
}
}
}
}// SPDX-License-Identifier: BUSL-1.1
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();
///@notice Returns the index of the call that failed within the SandboxRouter.Call[] array
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();// SPDX-License-Identifier: MIT
pragma solidity =0.8.21;
/**
* @dev Interface of the ERC20 standard as defined in the EIP.
*/
interface IERC20 {
/**
* @dev Emitted when `value` tokens are moved from one account (`from`) to
* another (`to`).
*
* Note that `value` may be zero.
*/
event Transfer(address indexed from, address indexed to, uint256 value);
/**
* @dev Emitted when the allowance of a `spender` for an `owner` is set by
* a call to {approve}. `value` is the new allowance.
*/
event Approval(
address indexed owner,
address indexed spender,
uint256 value
);
/**
* @dev Returns the amount of tokens in existence.
*/
function totalSupply() external view returns (uint256);
/**
* @dev Returns the amount of tokens owned by `account`.
*/
function balanceOf(address account) external view returns (uint256);
/**
* @dev Moves `amount` tokens from the caller's account to `to`.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transfer(address to, uint256 amount) external returns (bool);
/**
* @dev Returns the remaining number of tokens that `spender` will be
* allowed to spend on behalf of `owner` through {transferFrom}. This is
* zero by default.
*
* This value changes when {approve} or {transferFrom} are called.
*/
function allowance(address owner, address spender)
external
view
returns (uint256);
/**
* @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* IMPORTANT: Beware that changing an allowance with this method brings the risk
* that someone may use both the old and the new allowance by unfortunate
* transaction ordering. One possible solution to mitigate this race
* condition is to first reduce the spender's allowance to 0 and set the
* desired value afterwards:
* https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
*
* Emits an {Approval} event.
*/
function approve(address spender, uint256 amount) external returns (bool);
/**
* @dev Moves `amount` tokens from `from` to `to` using the
* allowance mechanism. `amount` is then deducted from the caller's
* allowance.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transferFrom(
address from,
address to,
uint256 amount
) external returns (bool);
function decimals() external view returns (uint8);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/utils/SafeERC20.sol)
pragma solidity ^0.8.0;
import "../../interfaces/token/IERC20.sol";
import "../../interfaces/token/draft-IERC20Permit.sol";
import "../../utils/Address.sol";
/**
* @title SafeERC20
* @dev Wrappers around ERC20 operations that throw on failure (when the token
* contract returns false). Tokens that return no value (and instead revert or
* throw on failure) are also supported, non-reverting calls are assumed to be
* successful.
* To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,
* which allows you to call the safe operations as `token.safeTransfer(...)`, etc.
*/
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));
}
/**
* @dev Deprecated. This function has issues similar to the ones found in
* {IERC20-approve}, and its usage is discouraged.
*
* Whenever possible, use {safeIncreaseAllowance} and
* {safeDecreaseAllowance} instead.
*/
function safeApprove(
IERC20 token,
address spender,
uint256 value
) internal {
// safeApprove should only be called when setting an initial allowance,
// or when resetting it to zero. To increase and decrease it, use
// 'safeIncreaseAllowance' and 'safeDecreaseAllowance'
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");
}
/**
* @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
* on the return value: the return value is optional (but if data is returned, it must not be false).
* @param token The token targeted by the call.
* @param data The call data (encoded using abi.encode or one of its variants).
*/
function _callOptionalReturn(IERC20 token, bytes memory data) private {
// We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since
// we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that
// the target address contains contract code and also asserts for success in the low-level call.
bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed");
if (returndata.length > 0) {
// Return data is optional
require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed");
}
}
}// SPDX-License-Identifier: UNLICENSED
pragma solidity =0.8.21;
import "../../lib/libraries/Uniswap/FullMath.sol";
library ConveyorMath {
/// @notice maximum uint128 64.64 fixed point number
uint128 private constant MAX_64x64 = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF;
uint256 private constant MAX_UINT64 = 0xFFFFFFFFFFFFFFFF;
/// @notice minimum int128 64.64 fixed point number
int128 private constant MIN_64x64 = -0x80000000000000000000000000000000;
/// @notice maximum uint256 128.128 fixed point number
uint256 private constant MAX_128x128 = 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff;
/// @notice helper function to transform uint256 number to uint128 64.64 fixed point representation
/// @param x unsigned 256 bit unsigned integer number
/// @return unsigned 64.64 unsigned fixed point number
function fromUInt256(uint256 x) internal pure returns (uint128) {
unchecked {
require(x <= MAX_UINT64);
return uint128(x << 64);
}
}
/// @notice helper function to transform 64.64 fixed point uint128 to uint64 integer number
/// @param x unsigned 64.64 fixed point number
/// @return unsigned uint64 integer representation
function toUInt64(uint128 x) internal pure returns (uint64) {
unchecked {
return uint64(x >> 64);
}
}
/// @notice helper function to transform uint128 to 128.128 fixed point representation
/// @param x uint128 unsigned integer
/// @return unsigned 128.128 unsigned fixed point number
function fromUInt128(uint128 x) internal pure returns (uint256) {
unchecked {
require(x <= 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);
return uint256(x) << 128;
}
}
/// @notice helper to convert 128x128 fixed point number to 64.64 fixed point number
/// @param x 128.128 unsigned fixed point number
/// @return unsigned 64.64 unsigned fixed point number
function from128x128(uint256 x) internal pure returns (uint128) {
unchecked {
uint256 answer = x >> 64;
require(answer >= 0x0 && answer <= MAX_64x64);
return uint128(answer);
}
}
/// @notice helper to convert 64.64 unsigned fixed point number to 128.128 fixed point number
/// @param x 64.64 unsigned fixed point number
/// @return unsigned 128.128 unsignned fixed point number
function to128x128(uint128 x) internal pure returns (uint256) {
unchecked {
return uint256(x) << 64;
}
}
/// @notice helper to add two unsigned 64.64 fixed point numbers
/// @param x 64.64 unsigned fixed point number
/// @param y 64.64 unsigned fixed point number
/// @return unsigned 64.64 unsigned fixed point number
function add64x64(uint128 x, uint128 y) internal pure returns (uint128) {
unchecked {
uint256 answer = uint256(x) + y;
require(answer <= MAX_64x64);
return uint128(answer);
}
}
/// @notice helper to add two signed 64.64 fixed point numbers
/// @param x 64.64 signed fixed point number
/// @param y 64.64 signed fixed point number
/// @return signed 64.64 unsigned fixed point number
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);
}
}
/// @notice helper to add two unsigened 128.128 fixed point numbers
/// @param x 128.128 unsigned fixed point number
/// @param y 128.128 unsigned fixed point number
/// @return unsigned 128.128 unsigned fixed point number
function add128x128(uint256 x, uint256 y) internal pure returns (uint256) {
uint256 answer = x + y;
return answer;
}
/// @notice helper to add unsigned 128.128 fixed point number with unsigned 64.64 fixed point number
/// @param x 128.128 unsigned fixed point number
/// @param y 64.64 unsigned fixed point number
/// @return unsigned 128.128 unsigned fixed point number
function add128x64(uint256 x, uint128 y) internal pure returns (uint256) {
uint256 answer = x + (uint256(y) << 64);
return answer;
}
/// @notice helper function to multiply two unsigned 64.64 fixed point numbers
/// @param x 64.64 unsigned fixed point number
/// @param y 64.64 unsigned fixed point number
/// @return unsigned
function mul64x64(uint128 x, uint128 y) internal pure returns (uint128) {
unchecked {
uint256 answer = (uint256(x) * y) >> 64;
require(answer <= MAX_64x64);
return uint128(answer);
}
}
/// @notice helper function to multiply a 128.128 fixed point number by a 64.64 fixed point number
/// @param x 128.128 unsigned fixed point number
/// @param y 64.64 unsigned fixed point number
/// @return unsigned
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;
}
/// @notice helper function to multiply unsigned 64.64 fixed point number by a unsigned integer
/// @param x 64.64 unsigned fixed point number
/// @param y uint256 unsigned integer
/// @return unsigned
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;
}
}
/// @notice helper function to multiply unsigned 128.128 fixed point number by a unsigned integer
/// @param x 128.128 unsigned fixed point number
/// @param y uint256 unsigned integer
/// @return unsigned
function mul128U(uint256 x, uint256 y) internal pure returns (uint256) {
if (y == 0 || x == 0) {
return 0;
}
return (x * y) >> 128;
}
///@notice helper to get the absolute value of a signed integer.
///@param x a signed integer.
///@return signed 256 bit integer representing the absolute value of x.
function abs(int256 x) internal pure returns (int256) {
unchecked {
return x < 0 ? -x : x;
}
}
/// @notice helper function to divide two unsigned 64.64 fixed point numbers
/// @param x 64.64 unsigned fixed point number
/// @param y 64.64 unsigned fixed point number
/// @return unsigned uint128 64.64 unsigned integer
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);
}
}
/// @notice helper function to divide two unsigned 128.128 fixed point numbers
/// @param x 128.128 unsigned fixed point number
/// @param y 128.128 unsigned fixed point number
/// @return unsigned uint128 128.128 unsigned integer
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;
}
}
/// @notice helper function to divide two unsigned integers
/// @param x uint256 unsigned integer number
/// @param y uint256 unsigned integer number
/// @return unsigned uint128 64.64 unsigned integer
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;
}
}
/// @param x uint256 unsigned integer
/// @param y uint256 unsigned integer
/// @return unsigned 64.64 fixed point number
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; // No need to shift xc anymore
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; // We rely on overflow behavior here
lo = hi << 128;
if (xl < lo) xh -= 1;
xl -= lo; // We rely on overflow behavior here
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;
}
/// @notice helper to calculate binary exponent of 64.64 unsigned fixed point number
/// @param x unsigned 64.64 fixed point number
/// @return unsigend 64.64 fixed point number
function exp_2(uint128 x) private pure returns (uint128) {
unchecked {
require(x < 0x400000000000000000); // Overflow
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));
}
}
/// @notice helper to compute the natural exponent of a 64.64 fixed point number
/// @param x 64.64 fixed point number
/// @return unsigned 64.64 fixed point number
function exp(uint128 x) internal pure returns (uint128) {
unchecked {
require(x < 0x400000000000000000, "Exponential overflow"); // Overflow
return exp_2(uint128((uint256(x) * 0x171547652B82FE1777D0FFDA0D23A7D12) >> 128));
}
}
/// @notice helper to compute the square root of an unsigned uint256 integer
/// @param x unsigned uint256 integer
/// @return unsigned 64.64 unsigned fixed point number
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; // Seven iterations should be enough
uint256 r1 = x / r;
return uint128(r < r1 ? r : r1);
}
}
}
}// SPDX-License-Identifier: BUSL-1.1
pragma solidity =0.8.21;
import {UniswapV3Callback} from "./UniswapV3Callback.sol";
import {AlgebraCallback} from "./AlgebraCallback.sol";
import {UniswapV2Callback} from "./UniswapV2Callback.sol";
import {TraderJoeCallback} from "./TraderJoeCallback.sol";
import {ZyberSwapElasticCallback} from "./ZyberSwapElasticCallback.sol";
import {ZyberSwapCallback} from "./ZyberSwapCallback.sol";
import {ArbDexCallback} from "./ArbDexCallback.sol";
import {ArbSwapCallback} from "./ArbSwapCallback.sol";
contract ConveyorSwapCallbacks is
UniswapV3Callback,
AlgebraCallback,
TraderJoeCallback,
UniswapV2Callback,
ZyberSwapElasticCallback,
ZyberSwapCallback,
ArbDexCallback,
ArbSwapCallback
{}// SPDX-License-Identifier: MIT
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);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-IERC20Permit.sol)
pragma solidity ^0.8.0;
/**
* @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in
* https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].
*
* Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by
* presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't
* need to send a transaction, and thus is not required to hold Ether at all.
*/
interface IERC20Permit {
/**
* @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,
* given ``owner``'s signed approval.
*
* IMPORTANT: The same issues {IERC20-approve} has related to transaction
* ordering also apply here.
*
* Emits an {Approval} event.
*
* Requirements:
*
* - `spender` cannot be the zero address.
* - `deadline` must be a timestamp in the future.
* - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`
* over the EIP712-formatted function arguments.
* - the signature must use ``owner``'s current nonce (see {nonces}).
*
* For more information on the signature format, see the
* https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP
* section].
*/
function permit(
address owner,
address spender,
uint256 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) external;
/**
* @dev Returns the current nonce for `owner`. This value must be
* included whenever a signature is generated for {permit}.
*
* Every successful call to {permit} increases ``owner``'s nonce by one. This
* prevents a signature from being used multiple times.
*/
function nonces(address owner) external view returns (uint256);
/**
* @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.
*/
// solhint-disable-next-line func-name-mixedcase
function DOMAIN_SEPARATOR() external view returns (bytes32);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol)
pragma solidity ^0.8.1;
/**
* @dev Collection of functions related to the address type
*/
library Address {
/**
* @dev Returns true if `account` is a contract.
*
* [IMPORTANT]
* ====
* It is unsafe to assume that an address for which this function returns
* false is an externally-owned account (EOA) and not a contract.
*
* Among others, `isContract` will return false for the following
* types of addresses:
*
* - an externally-owned account
* - a contract in construction
* - an address where a contract will be created
* - an address where a contract lived, but was destroyed
* ====
*
* [IMPORTANT]
* ====
* You shouldn't rely on `isContract` to protect against flash loan attacks!
*
* Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets
* like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract
* constructor.
* ====
*/
function isContract(address account) internal view returns (bool) {
// This method relies on extcodesize/address.code.length, which returns 0
// for contracts in construction, since the code is only stored at the end
// of the constructor execution.
return account.code.length > 0;
}
/**
* @dev Replacement for Solidity's `transfer`: sends `amount` wei to
* `recipient`, forwarding all available gas and reverting on errors.
*
* https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
* of certain opcodes, possibly making contracts go over the 2300 gas limit
* imposed by `transfer`, making them unable to receive funds via
* `transfer`. {sendValue} removes this limitation.
*
* https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].
*
* IMPORTANT: because control is transferred to `recipient`, care must be
* taken to not create reentrancy vulnerabilities. Consider using
* {ReentrancyGuard} or the
* https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
*/
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");
}
/**
* @dev Performs a Solidity function call using a low level `call`. A
* plain `call` is an unsafe replacement for a function call: use this
* function instead.
*
* If `target` reverts with a revert reason, it is bubbled up by this
* function (like regular Solidity function calls).
*
* Returns the raw returned data. To convert to the expected return value,
* use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
*
* Requirements:
*
* - `target` must be a contract.
* - calling `target` with `data` must not revert.
*
* _Available since v3.1._
*/
function functionCall(address target, bytes memory data) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0, "Address: low-level call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with
* `errorMessage` as a fallback revert reason when `target` reverts.
*
* _Available since v3.1._
*/
function functionCall(
address target,
bytes memory data,
string memory errorMessage
) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but also transferring `value` wei to `target`.
*
* Requirements:
*
* - the calling contract must have an ETH balance of at least `value`.
* - the called Solidity function must be `payable`.
*
* _Available since v3.1._
*/
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");
}
/**
* @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but
* with `errorMessage` as a fallback revert reason when `target` reverts.
*
* _Available since v3.1._
*/
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);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but performing a static call.
*
* _Available since v3.3._
*/
function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
return functionStaticCall(target, data, "Address: low-level static call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
* but performing a static call.
*
* _Available since v3.3._
*/
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);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but performing a delegate call.
*
* _Available since v3.4._
*/
function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
return functionDelegateCall(target, data, "Address: low-level delegate call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
* but performing a delegate call.
*
* _Available since v3.4._
*/
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);
}
/**
* @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling
* the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.
*
* _Available since v4.8._
*/
function verifyCallResultFromTarget(
address target,
bool success,
bytes memory returndata,
string memory errorMessage
) internal view returns (bytes memory) {
if (success) {
if (returndata.length == 0) {
// only check isContract if the call was successful and the return data is empty
// otherwise we already know that it was a contract
require(isContract(target), "Address: call to non-contract");
}
return returndata;
} else {
_revert(returndata, errorMessage);
}
}
/**
* @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the
* revert reason or using the provided one.
*
* _Available since v4.3._
*/
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 {
// Look for revert reason and bubble it up if present
if (returndata.length > 0) {
// The easiest way to bubble the revert reason is using memory via assembly
/// @solidity memory-safe-assembly
assembly {
let returndata_size := mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert(errorMessage);
}
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
/// @title Contains 512-bit math functions
/// @notice Facilitates multiplication and division that can have overflow of an intermediate value without any loss of precision
/// @dev Handles "phantom overflow" i.e., allows multiplication and division where an intermediate value overflows 256 bits
library FullMath {
/// @notice Calculates floor(a×b÷denominator) with full precision. Throws if result overflows a uint256 or denominator == 0
/// @param a The multiplicand
/// @param b The multiplier
/// @param denominator The divisor
/// @return result The 256-bit result
/// @dev Credit to Remco Bloemen under MIT license https://xn--2-umb.com/21/muldiv
function mulDiv(
uint256 a,
uint256 b,
uint256 denominator
) internal pure returns (uint256 result) {
unchecked {
// 512-bit multiply [prod1 prod0] = a * b
// Compute the product mod 2**256 and mod 2**256 - 1
// then use the Chinese Remainder Theorem to reconstruct
// the 512 bit result. The result is stored in two 256
// variables such that product = prod1 * 2**256 + prod0
uint256 prod0; // Least significant 256 bits of the product
uint256 prod1; // Most significant 256 bits of the product
assembly {
let mm := mulmod(a, b, not(0))
prod0 := mul(a, b)
prod1 := sub(sub(mm, prod0), lt(mm, prod0))
}
// Handle non-overflow cases, 256 by 256 division
if (prod1 == 0) {
require(denominator > 0);
assembly {
result := div(prod0, denominator)
}
return result;
}
// Make sure the result is less than 2**256.
// Also prevents denominator == 0
require(denominator > prod1);
///////////////////////////////////////////////
// 512 by 256 division.
///////////////////////////////////////////////
// Make division exact by subtracting the remainder from [prod1 prod0]
// Compute remainder using mulmod
uint256 remainder;
assembly {
remainder := mulmod(a, b, denominator)
}
// Subtract 256 bit number from 512 bit number
assembly {
prod1 := sub(prod1, gt(remainder, prod0))
prod0 := sub(prod0, remainder)
}
// Factor powers of two out of denominator
// Compute largest power of two divisor of denominator.
// Always >= 1.
uint256 twos = (0 - denominator) & denominator;
// Divide denominator by power of two
assembly {
denominator := div(denominator, twos)
}
// Divide [prod1 prod0] by the factors of two
assembly {
prod0 := div(prod0, twos)
}
// Shift in bits from prod1 into prod0. For this we need
// to flip `twos` such that it is 2**256 / twos.
// If twos is zero, then it becomes one
assembly {
twos := add(div(sub(0, twos), twos), 1)
}
prod0 |= prod1 * twos;
// Invert denominator mod 2**256
// Now that denominator is an odd number, it has an inverse
// modulo 2**256 such that denominator * inv = 1 mod 2**256.
// Compute the inverse by starting with a seed that is correct
// correct for four bits. That is, denominator * inv = 1 mod 2**4
uint256 inv = (3 * denominator) ^ 2;
// Now use Newton-Raphson iteration to improve the precision.
// Thanks to Hensel's lifting lemma, this also works in modular
// arithmetic, doubling the correct bits in each step.
inv *= 2 - denominator * inv; // inverse mod 2**8
inv *= 2 - denominator * inv; // inverse mod 2**16
inv *= 2 - denominator * inv; // inverse mod 2**32
inv *= 2 - denominator * inv; // inverse mod 2**64
inv *= 2 - denominator * inv; // inverse mod 2**128
inv *= 2 - denominator * inv; // inverse mod 2**256
// Because the division is now exact we can divide by multiplying
// with the modular inverse of denominator. This will give us the
// correct result modulo 2**256. Since the precoditions guarantee
// that the outcome is less than 2**256, this is the final result.
// We don't need to compute the high bits of the result and prod1
// is no longer required.
result = prod0 * inv;
return result;
}
}
/// @notice Calculates ceil(a×b÷denominator) with full precision. Throws if result overflows a uint256 or denominator == 0
/// @param a The multiplicand
/// @param b The multiplier
/// @param denominator The divisor
/// @return result The 256-bit 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++;
}
}
}
}// SPDX-License-Identifier: BUSL-1.1
pragma solidity =0.8.21;
contract UniswapV3Callback {
///@notice Uniswap V3 callback function called during a swap on a v3 liqudity pool.
///@param amount0Delta - The change in token0 reserves from the swap.
///@param amount1Delta - The change in token1 reserves from the swap.
///@param data - The data packed into the swap.
function uniswapV3SwapCallback(int256 amount0Delta, int256 amount1Delta, bytes calldata data) external {
assembly {
// Start at fmp
let freeMemoryPointer := mload(0x40)
let token := calldataload(data.offset)
mstore(freeMemoryPointer, 0xa9059cbb00000000000000000000000000000000000000000000000000000000)
mstore(add(freeMemoryPointer, 4), and(caller(), 0xffffffffffffffffffffffffffffffffffffffff)) // Append and mask the "to" argument.
switch slt(amount0Delta, 0)
case 0 { mstore(add(freeMemoryPointer, 36), amount0Delta) }
// Append the "amount" argument. Masking not required as it's a full 32 byte type.
default { mstore(add(freeMemoryPointer, 36), amount1Delta) } // Append the "amount" argument. Masking not required as it's a full 32 byte type.
if iszero(
and(
or(and(eq(mload(0), 1), gt(returndatasize(), 31)), iszero(returndatasize())),
call(gas(), token, 0, freeMemoryPointer, 68, 0, 32)
)
) {
// Revert if the call failed.
revert(0, 0)
}
}
}
}// SPDX-License-Identifier: BUSL-1.1
pragma solidity =0.8.21;
contract AlgebraCallback {
///@notice Algebra callback function called during a swap on a algebra liqudity pool.
///@param amount0Delta - The change in token0 reserves from the swap.
///@param amount1Delta - The change in token1 reserves from the swap.
///@param data - The data packed into the swap.
function algebraSwapCallback(int256 amount0Delta, int256 amount1Delta, bytes calldata data) external {
assembly {
// Start at fmp
let freeMemoryPointer := mload(0x40)
let token := calldataload(data.offset)
mstore(freeMemoryPointer, 0xa9059cbb00000000000000000000000000000000000000000000000000000000)
mstore(add(freeMemoryPointer, 4), and(caller(), 0xffffffffffffffffffffffffffffffffffffffff)) // Append and mask the "to" argument.
switch slt(amount0Delta, 0)
case 0 { mstore(add(freeMemoryPointer, 36), amount0Delta) }
// Append the "amount" argument. Masking not required as it's a full 32 byte type.
default { mstore(add(freeMemoryPointer, 36), amount1Delta) } // Append the "amount" argument. Masking not required as it's a full 32 byte type.
if iszero(
and(
or(and(eq(mload(0), 1), gt(returndatasize(), 31)), iszero(returndatasize())),
call(gas(), token, 0, freeMemoryPointer, 68, 0, 32)
)
) {
// Revert if the call failed.
revert(0, 0)
}
}
}
}// SPDX-License-Identifier: BUSL-1.1
pragma solidity =0.8.21;
contract UniswapV2Callback {
bytes4 private constant _UNISWAP_PAIR_RESERVES_CALL_SELECTOR = 0x0902f1ac; // getReserves()
/// @notice Uniswap v2 swap callback
/// @param amount0 - The change in token0 reserves from the swap.
/// @param amount1 - The change in token1 reserves from the swap.
/// @param data - The data packed into the swap.
function uniswapV2Call(address, uint256 amount0, uint256 amount1, bytes calldata data) external {
assembly {
// Start at fmp
let freeMemoryPointer := mload(0x40)
let token := calldataload(data.offset)
let fee := calldataload(add(data.offset, 0x20))
mstore(freeMemoryPointer, _UNISWAP_PAIR_RESERVES_CALL_SELECTOR) // getReserves()
if iszero(staticcall(gas(), caller(), freeMemoryPointer, 0x4, freeMemoryPointer, 0x40)) {
// Revert if the call failed.
revert(0, 0)
}
if iszero(eq(returndatasize(), 0x60)) {
// Revert if the return data size doesn't match the expected size.
revert(0, 0)
}
let reserve0 := mload(freeMemoryPointer)
let reserve1 := mload(add(freeMemoryPointer, 0x20))
mstore(freeMemoryPointer, 0xa9059cbb00000000000000000000000000000000000000000000000000000000)
mstore(add(freeMemoryPointer, 4), and(caller(), 0xffffffffffffffffffffffffffffffffffffffff)) // Append and mask the "to" argument.
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 if the call failed.
revert(0, 0)
}
}
}
}// SPDX-License-Identifier: BUSL-1.1
pragma solidity =0.8.21;
contract TraderJoeCallback {
bytes4 private constant _UNISWAP_PAIR_RESERVES_CALL_SELECTOR = 0x0902f1ac; // getReserves()
/// @notice TraderJoe swap callback
/// @param amount0 - The change in token0 reserves from the swap.
/// @param amount1 - The change in token1 reserves from the swap.
/// @param data - The data packed into the swap.
function joeCall(address, uint256 amount0, uint256 amount1, bytes calldata data) external {
assembly {
// Start at fmp
let freeMemoryPointer := mload(0x40)
let token := calldataload(data.offset)
let fee := calldataload(add(data.offset, 0x20))
mstore(freeMemoryPointer, _UNISWAP_PAIR_RESERVES_CALL_SELECTOR) // getReserves()
if iszero(staticcall(gas(), caller(), freeMemoryPointer, 0x4, freeMemoryPointer, 0x40)) {
// Revert if the call failed.
revert(0, 0)
}
if iszero(eq(returndatasize(), 0x60)) {
mstore(0, 0x85cd58dc00000000000000000000000000000000000000000000000000000000) // ReservesCallFailed()
revert(0, 4)
}
let reserve0 := mload(freeMemoryPointer)
let reserve1 := mload(add(freeMemoryPointer, 0x20))
mstore(freeMemoryPointer, 0xa9059cbb00000000000000000000000000000000000000000000000000000000)
mstore(add(freeMemoryPointer, 4), and(caller(), 0xffffffffffffffffffffffffffffffffffffffff)) // Append and mask the "to" argument.
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 if the call failed.
revert(0, 0)
}
}
}
}// SPDX-License-Identifier: BUSL-1.1
pragma solidity =0.8.21;
contract ZyberSwapElasticCallback {
///@notice ZyberSwap Elastic callback function called during a swap on a v3 liqudity pool.
///@param deltaQty0 - The change in token0 reserves from the swap.
///@param deltaQty1 - The change in token1 reserves from the swap.
///@param data - The data packed into the swap.
function swapCallback(int256 deltaQty0, int256 deltaQty1, bytes calldata data) external {
assembly {
// Start at fmp
let freeMemoryPointer := mload(0x40)
let token := calldataload(data.offset)
mstore(freeMemoryPointer, 0xa9059cbb00000000000000000000000000000000000000000000000000000000)
mstore(add(freeMemoryPointer, 4), and(caller(), 0xffffffffffffffffffffffffffffffffffffffff)) // Append and mask the "to" argument.
switch slt(deltaQty0, 0)
case 0 { mstore(add(freeMemoryPointer, 36), deltaQty0) }
// Append the "amount" argument. Masking not required as it's a full 32 byte type.
default { mstore(add(freeMemoryPointer, 36), deltaQty1) } // Append the "amount" argument. Masking not required as it's a full 32 byte type.
if iszero(
and(
or(and(eq(mload(0), 1), gt(returndatasize(), 31)), iszero(returndatasize())),
call(gas(), token, 0, freeMemoryPointer, 68, 0, 32)
)
) {
// Revert if the call failed.
revert(0, 0)
}
}
}
}// SPDX-License-Identifier: BUSL-1.1
pragma solidity =0.8.21;
contract ZyberSwapCallback {
bytes4 private constant _UNISWAP_PAIR_RESERVES_CALL_SELECTOR = 0x0902f1ac; // getReserves()
/// @notice Zyber swap callback
/// @param amount0 - The change in token0 reserves from the swap.
/// @param amount1 - The change in token1 reserves from the swap.
/// @param data - The data packed into the swap.
function ZyberCall(address, uint256 amount0, uint256 amount1, bytes calldata data) external {
assembly {
// Start at fmp
let freeMemoryPointer := mload(0x40)
let token := calldataload(data.offset)
let fee := calldataload(add(data.offset, 0x20))
mstore(freeMemoryPointer, _UNISWAP_PAIR_RESERVES_CALL_SELECTOR) // getReserves()
if iszero(staticcall(gas(), caller(), freeMemoryPointer, 0x4, freeMemoryPointer, 0x40)) {
// Revert if the call failed.
revert(0, 0)
}
if iszero(eq(returndatasize(), 0x60)) {
// Revert if the return data size doesn't match the expected size.
revert(0, 0)
}
let reserve0 := mload(freeMemoryPointer)
let reserve1 := mload(add(freeMemoryPointer, 0x20))
mstore(freeMemoryPointer, 0xa9059cbb00000000000000000000000000000000000000000000000000000000)
mstore(add(freeMemoryPointer, 4), and(caller(), 0xffffffffffffffffffffffffffffffffffffffff)) // Append and mask the "to" argument.
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 if the call failed.
revert(0, 0)
}
}
}
}// SPDX-License-Identifier: BUSL-1.1
pragma solidity =0.8.21;
contract ArbDexCallback {
bytes4 private constant _UNISWAP_PAIR_RESERVES_CALL_SELECTOR = 0x0902f1ac; // getReserves()
/// @notice ArbDex swap callback
/// @param amount0 - The change in token0 reserves from the swap.
/// @param amount1 - The change in token1 reserves from the swap.
/// @param data - The data packed into the swap.
function arbdexCall(address, uint256 amount0, uint256 amount1, bytes calldata data) external {
assembly {
// Start at fmp
let freeMemoryPointer := mload(0x40)
let token := calldataload(data.offset)
let fee := calldataload(add(data.offset, 0x20))
mstore(freeMemoryPointer, _UNISWAP_PAIR_RESERVES_CALL_SELECTOR) // getReserves()
if iszero(staticcall(gas(), caller(), freeMemoryPointer, 0x4, freeMemoryPointer, 0x40)) {
// Revert if the call failed.
revert(0, 0)
}
if iszero(eq(returndatasize(), 0x60)) {
mstore(0, 0x85cd58dc00000000000000000000000000000000000000000000000000000000) // ReservesCallFailed()
revert(0, 4)
}
let reserve0 := mload(freeMemoryPointer)
let reserve1 := mload(add(freeMemoryPointer, 0x20))
mstore(freeMemoryPointer, 0xa9059cbb00000000000000000000000000000000000000000000000000000000)
mstore(add(freeMemoryPointer, 4), and(caller(), 0xffffffffffffffffffffffffffffffffffffffff)) // Append and mask the "to" argument.
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 if the call failed.
revert(0, 0)
}
}
}
}// SPDX-License-Identifier: BUSL-1.1
pragma solidity =0.8.21;
contract ArbSwapCallback {
bytes4 private constant _UNISWAP_PAIR_RESERVES_CALL_SELECTOR = 0x0902f1ac; // getReserves()
/// @notice Arb swap callback
/// @param amount0 - The change in token0 reserves from the swap.
/// @param amount1 - The change in token1 reserves from the swap.
/// @param data - The data packed into the swap.
function swapCall(address, uint256 amount0, uint256 amount1, bytes calldata data) external {
assembly {
// Start at fmp
let freeMemoryPointer := mload(0x40)
let token := calldataload(data.offset)
let fee := calldataload(add(data.offset, 0x20))
mstore(freeMemoryPointer, _UNISWAP_PAIR_RESERVES_CALL_SELECTOR) // getReserves()
if iszero(staticcall(gas(), caller(), freeMemoryPointer, 0x4, freeMemoryPointer, 0x40)) {
// Revert if the call failed.
revert(0, 0)
}
if iszero(eq(returndatasize(), 0x60)) {
mstore(0, 0x85cd58dc00000000000000000000000000000000000000000000000000000000) // ReservesCallFailed()
revert(0, 4)
}
let reserve0 := mload(freeMemoryPointer)
let reserve1 := mload(add(freeMemoryPointer, 0x20))
mstore(freeMemoryPointer, 0xa9059cbb00000000000000000000000000000000000000000000000000000000)
mstore(add(freeMemoryPointer, 4), and(caller(), 0xffffffffffffffffffffffffffffffffffffffff)) // Append and mask the "to" argument.
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 if the call failed.
revert(0, 0)
}
}
}
}{
"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/"
],
"optimizer": {
"enabled": true,
"runs": 200
},
"metadata": {
"useLiteralContent": false,
"bytecodeHash": "ipfs",
"appendCBOR": true
},
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
},
"evmVersion": "paris",
"libraries": {}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"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"}]Contract Creation Code
60a060405260405162002070380380620020708339810160408190526200002691620000f0565b6001600160a01b038116620000815760405162461bcd60e51b815260206004820152601460248201527f574554482061646472657373206973207a65726f000000000000000000000000604482015260640160405180910390fd5b6040516200008f90620000e2565b604051809103906000f080158015620000ac573d6000803e3d6000fd5b50600080546001600160a01b039283166001600160a01b0319918216179091559116608052600180549091163217905562000122565b6105ac8062001ac483390190565b6000602082840312156200010357600080fd5b81516001600160a01b03811681146200011b57600080fd5b9392505050565b60805161196a6200015a600039600081816102fa01528181610596015281816105c401528181610e2b0152610ea7015261196a6000f3fe6080604052600436106101225760003560e01c80634f98ca73116100a0578063cdf1399211610064578063cdf1399214610344578063dac2d62014610357578063e18d7db71461036a578063e951cffc14610372578063f2fde38b146103a357600080fd5b80634f98ca73146102ad5780638920e96b146102cd578063ad5c4648146102e8578063bf2dcb8e1461031c578063cc29516a1461032f57600080fd5b8063267831c3116100e7578063267831c3146101ea57806327fa6f421461022057806334f887b5146102335780633702dbe4146102775780633ccfd60b1461029857600080fd5b806262102c1461012e57806305a7ee9d146101505780630c52e53d146101765780630e2c2a261461018957806314941f40146101d757600080fd5b3661012957005b600080fd5b34801561013a57600080fd5b5061014e610149366004611514565b6103c3565b005b61016361015e366004611560565b6104ad565b6040519081526020015b60405180910390f35b6101636101843660046115af565b6104c7565b34801561019557600080fd5b506101bf6101a43660046115ef565b6003602052600090815260409020546001600160a01b031681565b6040516001600160a01b03909116815260200161016d565b6101bf6101e5366004611629565b6104d7565b3480156101f657600080fd5b506101bf6102053660046115ef565b6004602052600090815260409020546001600160a01b031681565b61014e61022e366004611560565b610530565b34801561023f57600080fd5b5061026461024e366004611514565b60056020526000908152604090205461ffff1681565b60405161ffff909116815260200161016d565b34801561028357600080fd5b506007546102649062010000900461ffff1681565b3480156102a457600080fd5b5061014e61097c565b3480156102b957600080fd5b506000546101bf906001600160a01b031681565b3480156102d957600080fd5b506007546102649061ffff1681565b3480156102f457600080fd5b506101bf7f000000000000000000000000000000000000000000000000000000000000000081565b61014e61032a3660046115af565b6109e8565b34801561033b57600080fd5b5061014e610cf5565b610163610352366004611560565b610d40565b61014e610365366004611560565b610d4c565b61014e610fb5565b34801561037e57600080fd5b5061026461038d366004611514565b60066020526000908152604090205461ffff1681565b3480156103af57600080fd5b5061014e6103be366004611514565b6110a5565b6001546001600160a01b031633146103ee5760405163469a130f60e01b815260040160405180910390fd5b60075461ffff908116600081815260036020908152604080832080546001600160a01b0319166001600160a01b038816908117909155835260059091529020805461ffff19168217905560010190617fff908216106104945760405162461bcd60e51b815260206004820152601860248201527f416666696c69617465206e6f6e6365206f766572666c6f77000000000000000060448201526064015b60405180910390fd5b6007805461ffff191661ffff9290921691909117905550565b6000805a90506104bd8484610530565b5a90039392505050565b6000805a90506104bd84846109e8565b6001546000906001600160a01b031633146105055760405163469a130f60e01b815260040160405180910390fd5b8183516020850134f5803b61051957600080fd5b60008190556001600160a01b031690505b92915050565b3461054160608401604085016116de565b6001600160701b0316111561056957604051633c79c7bb60e11b815260040160405180910390fd5b600061057b60608401604085016116de565b61058e906001600160701b03163461171d565b90506105ba817f0000000000000000000000000000000000000000000000000000000000000000611119565b6001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001663a9059cbb6105f66020850185611514565b6040516001600160e01b031960e084901b1681526001600160a01b039091166004820152602481018490526044016020604051808303816000875af1158015610643573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106679190611730565b5060006106776020850185611514565b6040516370a0823160e01b81523360048201526001600160a01b0391909116906370a0823190602401602060405180830381865afa1580156106bd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106e19190611752565b905060006106f560408601602087016116de565b610708906001600160701b03168361176b565b600054604051639981ac3160e01b81529192506001600160a01b031690639981ac319061073990879060040161177e565b600060405180830381600087803b15801561075357600080fd5b505af1158015610767573d6000803e3d6000fd5b506000925061077c9150506020870187611514565b6040516370a0823160e01b81523360048201526001600160a01b0391909116906370a0823190602401602060405180830381865afa1580156107c2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107e69190611752565b905081811015610835576107fa818361171d565b61080a60408801602089016116de565b60405163d28d3eb560e01b815260048101929092526001600160701b0316602482015260440161048b565b61084560808701606088016115ef565b61ffff16156108de576000600381600161086560808b0160608c016115ef565b61ffff90811690911c1681526020810191909152604001600020546001600160a01b03169050806108a957604051630d554a4b60e21b815260040160405180910390fd5b6108dc816108d7674ccccccccccccae86108c960608c0160408d016116de565b6001600160701b0316611159565b6111c3565b505b6108ee60a08701608088016115ef565b61ffff1615610974576000600481600161090e60a08b0160808c016115ef565b61ffff90811690911c1681526020810191909152604001600020546001600160a01b03169050806109525760405163c1b6114f60e01b815260040160405180910390fd5b610972816108d7674ccccccccccccae86108c960608c0160408d016116de565b505b505050505050565b6001546001600160a01b031633146109a75760405163469a130f60e01b815260040160405180910390fd5b6109b133476111c3565b60405147815233907f884edad9ce6fa2440d8a54cc123490eb96d2768479d49ff9c7366125a94243649060200160405180910390a2565b610a30336109f96020840184611514565b610a0960608601604087016116de565b6001600160701b0316610a1f6020870187611514565b6001600160a01b03169291906111f4565b6000610a426040840160208501611514565b6040516370a0823160e01b81523360048201526001600160a01b0391909116906370a0823190602401602060405180830381865afa158015610a88573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610aac9190611752565b90506000610ac060808501606086016116de565b610ad3906001600160701b03168361176b565b600054604051639981ac3160e01b81529192506001600160a01b031690639981ac3190610b0490869060040161177e565b600060405180830381600087803b158015610b1e57600080fd5b505af1158015610b32573d6000803e3d6000fd5b5060009250610b4a9150506040860160208701611514565b6040516370a0823160e01b81523360048201526001600160a01b0391909116906370a0823190602401602060405180830381865afa158015610b90573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bb49190611752565b905081811015610bd857610bc8818361171d565b61080a60808701606088016116de565b610be860a08601608087016115ef565b61ffff1615610c645760006003816001610c0860a08a0160808b016115ef565b61ffff90811690911c1681526020810191909152604001600020546001600160a01b0316905080610c4c57604051630d554a4b60e21b815260040160405180910390fd5b610c62816108d7674ccccccccccccae834611159565b505b610c7460c0860160a087016115ef565b61ffff1615610cee5760006004816001610c9460c08a0160a08b016115ef565b61ffff90811690911c1681526020810191909152604001600020546001600160a01b0316905080610cd85760405163c1b6114f60e01b815260040160405180910390fd5b610974816108d7674ccccccccccccae834611159565b5050505050565b6002546001600160a01b03163314610d2057604051635c427cd960e01b815260040160405180910390fd5b600280546001600160a01b03199081169091556001805490911633179055565b6000805a90506104bd84845b6000610d5b6020830183611514565b6001600160a01b031614610d8a57610d8a33610d7a6020840184611514565b610a0960408601602087016116de565b33316000610d9e60608501604086016116de565b610db1906001600160701b03168361176b565b600054604051639981ac3160e01b81529192506001600160a01b031690639981ac3190610de290869060040161177e565b600060405180830381600087803b158015610dfc57600080fd5b505af1158015610e10573d6000803e3d6000fd5b50506040516370a0823160e01b8152306004820152600092507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031691506370a0823190602401602060405180830381865afa158015610e7b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e9f9190611752565b9050610ecb817f0000000000000000000000000000000000000000000000000000000000000000611254565b610ed533826111c3565b3331821115610ef957610ee933318361171d565b61080a60608701604088016116de565b610f0960808601606087016115ef565b61ffff1615610f855760006003816001610f2960808a0160608b016115ef565b61ffff90811690911c1681526020810191909152604001600020546001600160a01b0316905080610f6d57604051630d554a4b60e21b815260040160405180910390fd5b610f83816108d7674ccccccccccccae834611159565b505b610f9560a08601608087016115ef565b61ffff1615610cee5760006004816001610c9460a08a0160808b016115ef565b3360009081526006602052604090205461ffff1615610fe75760405163e39f25b960e01b815260040160405180910390fd5b60075461ffff620100009091048116600081815260046020908152604080832080546001600160a01b03191633908117909155835260069091529020805461ffff19168217905560010190617fff908216106110855760405162461bcd60e51b815260206004820152601760248201527f5265666572726572206e6f6e6365206f766572666c6f77000000000000000000604482015260640161048b565b6007805461ffff909216620100000263ffff000019909216919091179055565b6001546001600160a01b031633146110d05760405163469a130f60e01b815260040160405180910390fd5b6001600160a01b0381166110f75760405163e6c4247b60e01b815260040160405180910390fd5b600280546001600160a01b0319166001600160a01b0392909216919091179055565b630d0e30db60e41b600090815280808085855af161115557817f4e617469766520746f6b656e206465706f736974206661696c65640000000000fd5b5050565b600081158061116f57506001600160801b038316155b1561117c5750600061052a565b6001600160801b03838116908316810260401c90608084901c026001600160c01b038111156111aa57600080fd5b60401b81198111156111bb57600080fd5b019392505050565b600080600080600085875af19050806111ef5760405163b12d13eb60e01b815260040160405180910390fd5b505050565b604080516001600160a01b0385811660248301528416604482015260648082018490528251808303909101815260849091019091526020810180516001600160e01b03166323b872dd60e01b17905261124e908590611296565b50505050565b632e1a7d4d60e01b600052816004526000806044600080855af161115557817f4e617469766520546f6b656e205769746864726177206661696c656400000000fd5b60006112eb826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166113689092919063ffffffff16565b8051909150156111ef57808060200190518101906113099190611730565b6111ef5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b606482015260840161048b565b6060611377848460008561137f565b949350505050565b6060824710156113e05760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b606482015260840161048b565b600080866001600160a01b031685876040516113fc91906118e5565b60006040518083038185875af1925050503d8060008114611439576040519150601f19603f3d011682016040523d82523d6000602084013e61143e565b606091505b509150915061144f8783838761145a565b979650505050505050565b606083156114c95782516000036114c2576001600160a01b0385163b6114c25760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640161048b565b5081611377565b61137783838151156114de5781518083602001fd5b8060405162461bcd60e51b815260040161048b9190611901565b80356001600160a01b038116811461150f57600080fd5b919050565b60006020828403121561152657600080fd5b61152f826114f8565b9392505050565b600060a0828403121561154857600080fd5b50919050565b60006040828403121561154857600080fd5b60008060c0838503121561157357600080fd5b61157d8484611536565b915060a083013567ffffffffffffffff81111561159957600080fd5b6115a58582860161154e565b9150509250929050565b60008082840360e08112156115c357600080fd5b60c08112156115d157600080fd5b5082915060c083013567ffffffffffffffff81111561159957600080fd5b60006020828403121561160157600080fd5b813561ffff8116811461152f57600080fd5b634e487b7160e01b600052604160045260246000fd5b6000806040838503121561163c57600080fd5b823567ffffffffffffffff8082111561165457600080fd5b818501915085601f83011261166857600080fd5b81358181111561167a5761167a611613565b604051601f8201601f19908116603f011681019083821181831017156116a2576116a2611613565b816040528281528860208487010111156116bb57600080fd5b826020860160208301376000602093820184015298969091013596505050505050565b6000602082840312156116f057600080fd5b81356001600160701b038116811461152f57600080fd5b634e487b7160e01b600052601160045260246000fd5b8181038181111561052a5761052a611707565b60006020828403121561174257600080fd5b8151801515811461152f57600080fd5b60006020828403121561176457600080fd5b5051919050565b8082018082111561052a5761052a611707565b602080825260009060608084016001600160a01b038061179d886114f8565b168487015283870135601e198836030181126117b857600080fd5b8701803585820167ffffffffffffffff808311156117d557600080fd5b8260051b8036038313156117e857600080fd5b60408b8101819052968490528a016080908101966000918c0136879003605e19015b868410156118ae578d8a03607f19018252853581811261182957600080fd5b8801896118378e83016114f8565b168b5283810135603e1982360301811261185057600080fd5b01838101908d01358681111561186557600080fd5b80360382131561187457600080fd5b848e8d015280858d015280828e8e013760008c82018e0152601f01601f1916909a018b019950948b019460019390930192908b019061180a565b50979d9c50505050505050505050505050565b60005b838110156118dc5781810151838201526020016118c4565b50506000910152565b600082516118f78184602087016118c1565b9190910192915050565b60208152600082518060208401526119208160408501602087016118c1565b601f01601f1916919091016040019291505056fea26469706673582212203a1cc808b5bc0ef0d81311dcc6ef55013947a7778f7cef38a5e4d186323908b864736f6c63430008150033608060405234801561001057600080fd5b5061058c806100206000396000f3fe608060405234801561001057600080fd5b50600436106100935760003560e01c8063be3176f411610066578063be3176f4146100d3578063df9aee68146100d3578063ee22dd87146100d3578063fa461e33146100ad578063fa483e72146100ad57600080fd5b806310d1e85c146100985780632c8958f6146100ad57806385b354e1146100985780639981ac31146100c0575b600080fd5b6100ab6100a6366004610377565b6100e6565b005b6100ab6100bb3660046103df565b6101a5565b6100ab6100ce366004610432565b610203565b6100ab6100e1366004610377565b6102d3565b60405182356020840135630240bc6b60e21b8352604083600485335afa61010c57600080fd5b60603d1461011957600080fd5b8251602084015163a9059cbb60e01b85523360048601528715801561015857600184620186a0038b850302620186a08c85020204016024870152610174565b600184620186a0038a840302620186a08b860202040160248701525b50505050602060006044846000855af13d15601f3d1160016000511416171661019c57600080fd5b50505050505050565b60405163a9059cbb60e01b815233600482015282356000861280156101cf578560248401526101d6565b8660248401525b50602060006044846000855af13d15601f3d116001600051141617166101fb57600080fd5b505050505050565b60005b6102136020830183610474565b90508110156102cf57600061022b6020840184610474565b8381811061023b5761023b6104be565b905060200281019061024d91906104d4565b61025b9060208101906104f4565b905036600061026d6020860186610474565b8581811061027d5761027d6104be565b905060200281019061028f91906104d4565b61029d90602081019061050f565b915091506040518183823760008083836000885af16102c0573d6000803e3d6000fd5b50836001019350505050610206565b5050565b60405182356020840135630240bc6b60e21b8352604083600485335afa6102f957600080fd5b60603d1461011957632173563760e21b60005260046000fd5b80356001600160a01b038116811461032957600080fd5b919050565b60008083601f84011261034057600080fd5b50813567ffffffffffffffff81111561035857600080fd5b60208301915083602082850101111561037057600080fd5b9250929050565b60008060008060006080868803121561038f57600080fd5b61039886610312565b94506020860135935060408601359250606086013567ffffffffffffffff8111156103c257600080fd5b6103ce8882890161032e565b969995985093965092949392505050565b600080600080606085870312156103f557600080fd5b8435935060208501359250604085013567ffffffffffffffff81111561041a57600080fd5b6104268782880161032e565b95989497509550505050565b60006020828403121561044457600080fd5b813567ffffffffffffffff81111561045b57600080fd5b82016040818503121561046d57600080fd5b9392505050565b6000808335601e1984360301811261048b57600080fd5b83018035915067ffffffffffffffff8211156104a657600080fd5b6020019150600581901b360382131561037057600080fd5b634e487b7160e01b600052603260045260246000fd5b60008235603e198336030181126104ea57600080fd5b9190910192915050565b60006020828403121561050657600080fd5b61046d82610312565b6000808335601e1984360301811261052657600080fd5b83018035915067ffffffffffffffff82111561054157600080fd5b60200191503681900382131561037057600080fdfea2646970667358221220322e91d0c342cf56bc60cb87bd1a05ef60afe7f6378a0d85c6037c9be3d94a6e64736f6c6343000815003300000000000000000000000082af49447d8a07e3bd95bd0d56f35241523fbab1
Deployed Bytecode
0x6080604052600436106101225760003560e01c80634f98ca73116100a0578063cdf1399211610064578063cdf1399214610344578063dac2d62014610357578063e18d7db71461036a578063e951cffc14610372578063f2fde38b146103a357600080fd5b80634f98ca73146102ad5780638920e96b146102cd578063ad5c4648146102e8578063bf2dcb8e1461031c578063cc29516a1461032f57600080fd5b8063267831c3116100e7578063267831c3146101ea57806327fa6f421461022057806334f887b5146102335780633702dbe4146102775780633ccfd60b1461029857600080fd5b806262102c1461012e57806305a7ee9d146101505780630c52e53d146101765780630e2c2a261461018957806314941f40146101d757600080fd5b3661012957005b600080fd5b34801561013a57600080fd5b5061014e610149366004611514565b6103c3565b005b61016361015e366004611560565b6104ad565b6040519081526020015b60405180910390f35b6101636101843660046115af565b6104c7565b34801561019557600080fd5b506101bf6101a43660046115ef565b6003602052600090815260409020546001600160a01b031681565b6040516001600160a01b03909116815260200161016d565b6101bf6101e5366004611629565b6104d7565b3480156101f657600080fd5b506101bf6102053660046115ef565b6004602052600090815260409020546001600160a01b031681565b61014e61022e366004611560565b610530565b34801561023f57600080fd5b5061026461024e366004611514565b60056020526000908152604090205461ffff1681565b60405161ffff909116815260200161016d565b34801561028357600080fd5b506007546102649062010000900461ffff1681565b3480156102a457600080fd5b5061014e61097c565b3480156102b957600080fd5b506000546101bf906001600160a01b031681565b3480156102d957600080fd5b506007546102649061ffff1681565b3480156102f457600080fd5b506101bf7f00000000000000000000000082af49447d8a07e3bd95bd0d56f35241523fbab181565b61014e61032a3660046115af565b6109e8565b34801561033b57600080fd5b5061014e610cf5565b610163610352366004611560565b610d40565b61014e610365366004611560565b610d4c565b61014e610fb5565b34801561037e57600080fd5b5061026461038d366004611514565b60066020526000908152604090205461ffff1681565b3480156103af57600080fd5b5061014e6103be366004611514565b6110a5565b6001546001600160a01b031633146103ee5760405163469a130f60e01b815260040160405180910390fd5b60075461ffff908116600081815260036020908152604080832080546001600160a01b0319166001600160a01b038816908117909155835260059091529020805461ffff19168217905560010190617fff908216106104945760405162461bcd60e51b815260206004820152601860248201527f416666696c69617465206e6f6e6365206f766572666c6f77000000000000000060448201526064015b60405180910390fd5b6007805461ffff191661ffff9290921691909117905550565b6000805a90506104bd8484610530565b5a90039392505050565b6000805a90506104bd84846109e8565b6001546000906001600160a01b031633146105055760405163469a130f60e01b815260040160405180910390fd5b8183516020850134f5803b61051957600080fd5b60008190556001600160a01b031690505b92915050565b3461054160608401604085016116de565b6001600160701b0316111561056957604051633c79c7bb60e11b815260040160405180910390fd5b600061057b60608401604085016116de565b61058e906001600160701b03163461171d565b90506105ba817f00000000000000000000000082af49447d8a07e3bd95bd0d56f35241523fbab1611119565b6001600160a01b037f00000000000000000000000082af49447d8a07e3bd95bd0d56f35241523fbab11663a9059cbb6105f66020850185611514565b6040516001600160e01b031960e084901b1681526001600160a01b039091166004820152602481018490526044016020604051808303816000875af1158015610643573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106679190611730565b5060006106776020850185611514565b6040516370a0823160e01b81523360048201526001600160a01b0391909116906370a0823190602401602060405180830381865afa1580156106bd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106e19190611752565b905060006106f560408601602087016116de565b610708906001600160701b03168361176b565b600054604051639981ac3160e01b81529192506001600160a01b031690639981ac319061073990879060040161177e565b600060405180830381600087803b15801561075357600080fd5b505af1158015610767573d6000803e3d6000fd5b506000925061077c9150506020870187611514565b6040516370a0823160e01b81523360048201526001600160a01b0391909116906370a0823190602401602060405180830381865afa1580156107c2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107e69190611752565b905081811015610835576107fa818361171d565b61080a60408801602089016116de565b60405163d28d3eb560e01b815260048101929092526001600160701b0316602482015260440161048b565b61084560808701606088016115ef565b61ffff16156108de576000600381600161086560808b0160608c016115ef565b61ffff90811690911c1681526020810191909152604001600020546001600160a01b03169050806108a957604051630d554a4b60e21b815260040160405180910390fd5b6108dc816108d7674ccccccccccccae86108c960608c0160408d016116de565b6001600160701b0316611159565b6111c3565b505b6108ee60a08701608088016115ef565b61ffff1615610974576000600481600161090e60a08b0160808c016115ef565b61ffff90811690911c1681526020810191909152604001600020546001600160a01b03169050806109525760405163c1b6114f60e01b815260040160405180910390fd5b610972816108d7674ccccccccccccae86108c960608c0160408d016116de565b505b505050505050565b6001546001600160a01b031633146109a75760405163469a130f60e01b815260040160405180910390fd5b6109b133476111c3565b60405147815233907f884edad9ce6fa2440d8a54cc123490eb96d2768479d49ff9c7366125a94243649060200160405180910390a2565b610a30336109f96020840184611514565b610a0960608601604087016116de565b6001600160701b0316610a1f6020870187611514565b6001600160a01b03169291906111f4565b6000610a426040840160208501611514565b6040516370a0823160e01b81523360048201526001600160a01b0391909116906370a0823190602401602060405180830381865afa158015610a88573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610aac9190611752565b90506000610ac060808501606086016116de565b610ad3906001600160701b03168361176b565b600054604051639981ac3160e01b81529192506001600160a01b031690639981ac3190610b0490869060040161177e565b600060405180830381600087803b158015610b1e57600080fd5b505af1158015610b32573d6000803e3d6000fd5b5060009250610b4a9150506040860160208701611514565b6040516370a0823160e01b81523360048201526001600160a01b0391909116906370a0823190602401602060405180830381865afa158015610b90573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bb49190611752565b905081811015610bd857610bc8818361171d565b61080a60808701606088016116de565b610be860a08601608087016115ef565b61ffff1615610c645760006003816001610c0860a08a0160808b016115ef565b61ffff90811690911c1681526020810191909152604001600020546001600160a01b0316905080610c4c57604051630d554a4b60e21b815260040160405180910390fd5b610c62816108d7674ccccccccccccae834611159565b505b610c7460c0860160a087016115ef565b61ffff1615610cee5760006004816001610c9460c08a0160a08b016115ef565b61ffff90811690911c1681526020810191909152604001600020546001600160a01b0316905080610cd85760405163c1b6114f60e01b815260040160405180910390fd5b610974816108d7674ccccccccccccae834611159565b5050505050565b6002546001600160a01b03163314610d2057604051635c427cd960e01b815260040160405180910390fd5b600280546001600160a01b03199081169091556001805490911633179055565b6000805a90506104bd84845b6000610d5b6020830183611514565b6001600160a01b031614610d8a57610d8a33610d7a6020840184611514565b610a0960408601602087016116de565b33316000610d9e60608501604086016116de565b610db1906001600160701b03168361176b565b600054604051639981ac3160e01b81529192506001600160a01b031690639981ac3190610de290869060040161177e565b600060405180830381600087803b158015610dfc57600080fd5b505af1158015610e10573d6000803e3d6000fd5b50506040516370a0823160e01b8152306004820152600092507f00000000000000000000000082af49447d8a07e3bd95bd0d56f35241523fbab16001600160a01b031691506370a0823190602401602060405180830381865afa158015610e7b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e9f9190611752565b9050610ecb817f00000000000000000000000082af49447d8a07e3bd95bd0d56f35241523fbab1611254565b610ed533826111c3565b3331821115610ef957610ee933318361171d565b61080a60608701604088016116de565b610f0960808601606087016115ef565b61ffff1615610f855760006003816001610f2960808a0160608b016115ef565b61ffff90811690911c1681526020810191909152604001600020546001600160a01b0316905080610f6d57604051630d554a4b60e21b815260040160405180910390fd5b610f83816108d7674ccccccccccccae834611159565b505b610f9560a08601608087016115ef565b61ffff1615610cee5760006004816001610c9460a08a0160808b016115ef565b3360009081526006602052604090205461ffff1615610fe75760405163e39f25b960e01b815260040160405180910390fd5b60075461ffff620100009091048116600081815260046020908152604080832080546001600160a01b03191633908117909155835260069091529020805461ffff19168217905560010190617fff908216106110855760405162461bcd60e51b815260206004820152601760248201527f5265666572726572206e6f6e6365206f766572666c6f77000000000000000000604482015260640161048b565b6007805461ffff909216620100000263ffff000019909216919091179055565b6001546001600160a01b031633146110d05760405163469a130f60e01b815260040160405180910390fd5b6001600160a01b0381166110f75760405163e6c4247b60e01b815260040160405180910390fd5b600280546001600160a01b0319166001600160a01b0392909216919091179055565b630d0e30db60e41b600090815280808085855af161115557817f4e617469766520746f6b656e206465706f736974206661696c65640000000000fd5b5050565b600081158061116f57506001600160801b038316155b1561117c5750600061052a565b6001600160801b03838116908316810260401c90608084901c026001600160c01b038111156111aa57600080fd5b60401b81198111156111bb57600080fd5b019392505050565b600080600080600085875af19050806111ef5760405163b12d13eb60e01b815260040160405180910390fd5b505050565b604080516001600160a01b0385811660248301528416604482015260648082018490528251808303909101815260849091019091526020810180516001600160e01b03166323b872dd60e01b17905261124e908590611296565b50505050565b632e1a7d4d60e01b600052816004526000806044600080855af161115557817f4e617469766520546f6b656e205769746864726177206661696c656400000000fd5b60006112eb826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166113689092919063ffffffff16565b8051909150156111ef57808060200190518101906113099190611730565b6111ef5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b606482015260840161048b565b6060611377848460008561137f565b949350505050565b6060824710156113e05760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b606482015260840161048b565b600080866001600160a01b031685876040516113fc91906118e5565b60006040518083038185875af1925050503d8060008114611439576040519150601f19603f3d011682016040523d82523d6000602084013e61143e565b606091505b509150915061144f8783838761145a565b979650505050505050565b606083156114c95782516000036114c2576001600160a01b0385163b6114c25760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640161048b565b5081611377565b61137783838151156114de5781518083602001fd5b8060405162461bcd60e51b815260040161048b9190611901565b80356001600160a01b038116811461150f57600080fd5b919050565b60006020828403121561152657600080fd5b61152f826114f8565b9392505050565b600060a0828403121561154857600080fd5b50919050565b60006040828403121561154857600080fd5b60008060c0838503121561157357600080fd5b61157d8484611536565b915060a083013567ffffffffffffffff81111561159957600080fd5b6115a58582860161154e565b9150509250929050565b60008082840360e08112156115c357600080fd5b60c08112156115d157600080fd5b5082915060c083013567ffffffffffffffff81111561159957600080fd5b60006020828403121561160157600080fd5b813561ffff8116811461152f57600080fd5b634e487b7160e01b600052604160045260246000fd5b6000806040838503121561163c57600080fd5b823567ffffffffffffffff8082111561165457600080fd5b818501915085601f83011261166857600080fd5b81358181111561167a5761167a611613565b604051601f8201601f19908116603f011681019083821181831017156116a2576116a2611613565b816040528281528860208487010111156116bb57600080fd5b826020860160208301376000602093820184015298969091013596505050505050565b6000602082840312156116f057600080fd5b81356001600160701b038116811461152f57600080fd5b634e487b7160e01b600052601160045260246000fd5b8181038181111561052a5761052a611707565b60006020828403121561174257600080fd5b8151801515811461152f57600080fd5b60006020828403121561176457600080fd5b5051919050565b8082018082111561052a5761052a611707565b602080825260009060608084016001600160a01b038061179d886114f8565b168487015283870135601e198836030181126117b857600080fd5b8701803585820167ffffffffffffffff808311156117d557600080fd5b8260051b8036038313156117e857600080fd5b60408b8101819052968490528a016080908101966000918c0136879003605e19015b868410156118ae578d8a03607f19018252853581811261182957600080fd5b8801896118378e83016114f8565b168b5283810135603e1982360301811261185057600080fd5b01838101908d01358681111561186557600080fd5b80360382131561187457600080fd5b848e8d015280858d015280828e8e013760008c82018e0152601f01601f1916909a018b019950948b019460019390930192908b019061180a565b50979d9c50505050505050505050505050565b60005b838110156118dc5781810151838201526020016118c4565b50506000910152565b600082516118f78184602087016118c1565b9190910192915050565b60208152600082518060208401526119208160408501602087016118c1565b601f01601f1916919091016040019291505056fea26469706673582212203a1cc808b5bc0ef0d81311dcc6ef55013947a7778f7cef38a5e4d186323908b864736f6c63430008150033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
00000000000000000000000082af49447d8a07e3bd95bd0d56f35241523fbab1
-----Decoded View---------------
Arg [0] : _weth (address): 0x82aF49447D8a07e3bd95BD0d56f35241523fBab1
-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 00000000000000000000000082af49447d8a07e3bd95bd0d56f35241523fbab1
Loading...
Loading
Loading...
Loading
Loading...
Loading
Net Worth in USD
$146.54
Net Worth in ETH
0.051188
Token Allocations
ETH
81.90%
BNB
18.04%
POL
0.06%
Multichain Portfolio | 35 Chains
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.