Feature Tip: Add private address tag to any address under My Name Tag !
Source Code
| Transaction Hash |
Method
|
Block
|
From
|
|
To
|
||||
|---|---|---|---|---|---|---|---|---|---|
Latest 25 internal transactions (View All)
Advanced mode:
| Parent Transaction Hash | Method | Block |
From
|
|
To
|
||
|---|---|---|---|---|---|---|---|
| Deposit | 20645063 | 551 days ago | 55.66959078 ETH | ||||
| Transfer | 20645063 | 551 days ago | 55.66959078 ETH | ||||
| Deposit | 20623369 | 554 days ago | 0.01235257 ETH | ||||
| Transfer | 20623369 | 554 days ago | 0.01235257 ETH | ||||
| Deposit | 20601893 | 557 days ago | 0.02154299 ETH | ||||
| Transfer | 20601893 | 557 days ago | 0.02154299 ETH | ||||
| Deposit | 20580431 | 560 days ago | 0.00755693 ETH | ||||
| Transfer | 20580431 | 560 days ago | 0.00755693 ETH | ||||
| Deposit | 20558959 | 563 days ago | 0.02127236 ETH | ||||
| Transfer | 20558959 | 563 days ago | 0.02127236 ETH | ||||
| Deposit | 20537464 | 566 days ago | 0.02168297 ETH | ||||
| Transfer | 20537464 | 566 days ago | 0.02168297 ETH | ||||
| Deposit | 20515982 | 569 days ago | 0.0220106 ETH | ||||
| Transfer | 20515982 | 569 days ago | 0.0220106 ETH | ||||
| Deposit | 20494486 | 572 days ago | 0.02093508 ETH | ||||
| Transfer | 20494486 | 572 days ago | 0.02093508 ETH | ||||
| Deposit | 20472972 | 575 days ago | 0.02087202 ETH | ||||
| Transfer | 20472972 | 575 days ago | 0.02087202 ETH | ||||
| Deposit | 20451461 | 578 days ago | 0.18688666 ETH | ||||
| Transfer | 20451461 | 578 days ago | 0.18688666 ETH | ||||
| Deposit | 20429975 | 581 days ago | 0.01820656 ETH | ||||
| Transfer | 20429975 | 581 days ago | 0.01820656 ETH | ||||
| Deposit | 20408499 | 584 days ago | 0.01641224 ETH | ||||
| Transfer | 20408499 | 584 days ago | 0.01641224 ETH | ||||
| Deposit | 20387002 | 587 days ago | 0.01654539 ETH |
Loading...
Loading
Loading...
Loading
Cross-Chain Transactions
Loading...
Loading
Contract Name:
WethStrategyStargate
Compiler Version
v0.8.9+commit.e5eed63a
Contract Source Code (Solidity)
/**
*Submitted for verification at Etherscan.io on 2023-11-15
*/
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity 0.8.9;
library console {
address constant CONSOLE_ADDRESS = address(0x000000000000000000636F6e736F6c652e6c6f67);
function _sendLogPayload(bytes memory payload) private view {
uint256 payloadLength = payload.length;
address consoleAddress = CONSOLE_ADDRESS;
/// @solidity memory-safe-assembly
assembly {
let payloadStart := add(payload, 32)
let r := staticcall(gas(), consoleAddress, payloadStart, payloadLength, 0, 0)
}
}
function log() internal view {
_sendLogPayload(abi.encodeWithSignature("log()"));
}
function logInt(int p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(int)", p0));
}
function logUint(uint p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint)", p0));
}
function logString(string memory p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string)", p0));
}
function logBool(bool p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool)", p0));
}
function logAddress(address p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address)", p0));
}
function logBytes(bytes memory p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bytes)", p0));
}
function logBytes1(bytes1 p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bytes1)", p0));
}
function logBytes2(bytes2 p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bytes2)", p0));
}
function logBytes3(bytes3 p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bytes3)", p0));
}
function logBytes4(bytes4 p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bytes4)", p0));
}
function logBytes5(bytes5 p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bytes5)", p0));
}
function logBytes6(bytes6 p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bytes6)", p0));
}
function logBytes7(bytes7 p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bytes7)", p0));
}
function logBytes8(bytes8 p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bytes8)", p0));
}
function logBytes9(bytes9 p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bytes9)", p0));
}
function logBytes10(bytes10 p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bytes10)", p0));
}
function logBytes11(bytes11 p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bytes11)", p0));
}
function logBytes12(bytes12 p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bytes12)", p0));
}
function logBytes13(bytes13 p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bytes13)", p0));
}
function logBytes14(bytes14 p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bytes14)", p0));
}
function logBytes15(bytes15 p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bytes15)", p0));
}
function logBytes16(bytes16 p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bytes16)", p0));
}
function logBytes17(bytes17 p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bytes17)", p0));
}
function logBytes18(bytes18 p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bytes18)", p0));
}
function logBytes19(bytes19 p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bytes19)", p0));
}
function logBytes20(bytes20 p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bytes20)", p0));
}
function logBytes21(bytes21 p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bytes21)", p0));
}
function logBytes22(bytes22 p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bytes22)", p0));
}
function logBytes23(bytes23 p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bytes23)", p0));
}
function logBytes24(bytes24 p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bytes24)", p0));
}
function logBytes25(bytes25 p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bytes25)", p0));
}
function logBytes26(bytes26 p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bytes26)", p0));
}
function logBytes27(bytes27 p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bytes27)", p0));
}
function logBytes28(bytes28 p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bytes28)", p0));
}
function logBytes29(bytes29 p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bytes29)", p0));
}
function logBytes30(bytes30 p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bytes30)", p0));
}
function logBytes31(bytes31 p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bytes31)", p0));
}
function logBytes32(bytes32 p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bytes32)", p0));
}
function log(uint p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint)", p0));
}
function log(string memory p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string)", p0));
}
function log(bool p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool)", p0));
}
function log(address p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address)", p0));
}
function log(uint p0, uint p1) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,uint)", p0, p1));
}
function log(uint p0, string memory p1) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,string)", p0, p1));
}
function log(uint p0, bool p1) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,bool)", p0, p1));
}
function log(uint p0, address p1) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,address)", p0, p1));
}
function log(string memory p0, uint p1) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,uint)", p0, p1));
}
function log(string memory p0, string memory p1) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,string)", p0, p1));
}
function log(string memory p0, bool p1) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,bool)", p0, p1));
}
function log(string memory p0, address p1) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,address)", p0, p1));
}
function log(bool p0, uint p1) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,uint)", p0, p1));
}
function log(bool p0, string memory p1) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,string)", p0, p1));
}
function log(bool p0, bool p1) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,bool)", p0, p1));
}
function log(bool p0, address p1) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,address)", p0, p1));
}
function log(address p0, uint p1) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,uint)", p0, p1));
}
function log(address p0, string memory p1) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,string)", p0, p1));
}
function log(address p0, bool p1) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,bool)", p0, p1));
}
function log(address p0, address p1) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,address)", p0, p1));
}
function log(uint p0, uint p1, uint p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,uint,uint)", p0, p1, p2));
}
function log(uint p0, uint p1, string memory p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,uint,string)", p0, p1, p2));
}
function log(uint p0, uint p1, bool p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,uint,bool)", p0, p1, p2));
}
function log(uint p0, uint p1, address p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,uint,address)", p0, p1, p2));
}
function log(uint p0, string memory p1, uint p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,string,uint)", p0, p1, p2));
}
function log(uint p0, string memory p1, string memory p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,string,string)", p0, p1, p2));
}
function log(uint p0, string memory p1, bool p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,string,bool)", p0, p1, p2));
}
function log(uint p0, string memory p1, address p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,string,address)", p0, p1, p2));
}
function log(uint p0, bool p1, uint p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,bool,uint)", p0, p1, p2));
}
function log(uint p0, bool p1, string memory p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,bool,string)", p0, p1, p2));
}
function log(uint p0, bool p1, bool p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,bool,bool)", p0, p1, p2));
}
function log(uint p0, bool p1, address p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,bool,address)", p0, p1, p2));
}
function log(uint p0, address p1, uint p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,address,uint)", p0, p1, p2));
}
function log(uint p0, address p1, string memory p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,address,string)", p0, p1, p2));
}
function log(uint p0, address p1, bool p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,address,bool)", p0, p1, p2));
}
function log(uint p0, address p1, address p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,address,address)", p0, p1, p2));
}
function log(string memory p0, uint p1, uint p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,uint,uint)", p0, p1, p2));
}
function log(string memory p0, uint p1, string memory p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,uint,string)", p0, p1, p2));
}
function log(string memory p0, uint p1, bool p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,uint,bool)", p0, p1, p2));
}
function log(string memory p0, uint p1, address p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,uint,address)", p0, p1, p2));
}
function log(string memory p0, string memory p1, uint p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,string,uint)", p0, p1, p2));
}
function log(string memory p0, string memory p1, string memory p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,string,string)", p0, p1, p2));
}
function log(string memory p0, string memory p1, bool p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,string,bool)", p0, p1, p2));
}
function log(string memory p0, string memory p1, address p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,string,address)", p0, p1, p2));
}
function log(string memory p0, bool p1, uint p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,bool,uint)", p0, p1, p2));
}
function log(string memory p0, bool p1, string memory p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,bool,string)", p0, p1, p2));
}
function log(string memory p0, bool p1, bool p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,bool,bool)", p0, p1, p2));
}
function log(string memory p0, bool p1, address p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,bool,address)", p0, p1, p2));
}
function log(string memory p0, address p1, uint p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,address,uint)", p0, p1, p2));
}
function log(string memory p0, address p1, string memory p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,address,string)", p0, p1, p2));
}
function log(string memory p0, address p1, bool p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,address,bool)", p0, p1, p2));
}
function log(string memory p0, address p1, address p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,address,address)", p0, p1, p2));
}
function log(bool p0, uint p1, uint p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,uint,uint)", p0, p1, p2));
}
function log(bool p0, uint p1, string memory p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,uint,string)", p0, p1, p2));
}
function log(bool p0, uint p1, bool p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,uint,bool)", p0, p1, p2));
}
function log(bool p0, uint p1, address p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,uint,address)", p0, p1, p2));
}
function log(bool p0, string memory p1, uint p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,string,uint)", p0, p1, p2));
}
function log(bool p0, string memory p1, string memory p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,string,string)", p0, p1, p2));
}
function log(bool p0, string memory p1, bool p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,string,bool)", p0, p1, p2));
}
function log(bool p0, string memory p1, address p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,string,address)", p0, p1, p2));
}
function log(bool p0, bool p1, uint p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint)", p0, p1, p2));
}
function log(bool p0, bool p1, string memory p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,bool,string)", p0, p1, p2));
}
function log(bool p0, bool p1, bool p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool)", p0, p1, p2));
}
function log(bool p0, bool p1, address p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,bool,address)", p0, p1, p2));
}
function log(bool p0, address p1, uint p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,address,uint)", p0, p1, p2));
}
function log(bool p0, address p1, string memory p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,address,string)", p0, p1, p2));
}
function log(bool p0, address p1, bool p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,address,bool)", p0, p1, p2));
}
function log(bool p0, address p1, address p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,address,address)", p0, p1, p2));
}
function log(address p0, uint p1, uint p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,uint,uint)", p0, p1, p2));
}
function log(address p0, uint p1, string memory p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,uint,string)", p0, p1, p2));
}
function log(address p0, uint p1, bool p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,uint,bool)", p0, p1, p2));
}
function log(address p0, uint p1, address p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,uint,address)", p0, p1, p2));
}
function log(address p0, string memory p1, uint p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,string,uint)", p0, p1, p2));
}
function log(address p0, string memory p1, string memory p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,string,string)", p0, p1, p2));
}
function log(address p0, string memory p1, bool p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,string,bool)", p0, p1, p2));
}
function log(address p0, string memory p1, address p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,string,address)", p0, p1, p2));
}
function log(address p0, bool p1, uint p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,bool,uint)", p0, p1, p2));
}
function log(address p0, bool p1, string memory p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,bool,string)", p0, p1, p2));
}
function log(address p0, bool p1, bool p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,bool,bool)", p0, p1, p2));
}
function log(address p0, bool p1, address p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,bool,address)", p0, p1, p2));
}
function log(address p0, address p1, uint p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,address,uint)", p0, p1, p2));
}
function log(address p0, address p1, string memory p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,address,string)", p0, p1, p2));
}
function log(address p0, address p1, bool p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,address,bool)", p0, p1, p2));
}
function log(address p0, address p1, address p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,address,address)", p0, p1, p2));
}
function log(uint p0, uint p1, uint p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,uint,uint,uint)", p0, p1, p2, p3));
}
function log(uint p0, uint p1, uint p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,uint,uint,string)", p0, p1, p2, p3));
}
function log(uint p0, uint p1, uint p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,uint,uint,bool)", p0, p1, p2, p3));
}
function log(uint p0, uint p1, uint p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,uint,uint,address)", p0, p1, p2, p3));
}
function log(uint p0, uint p1, string memory p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,uint,string,uint)", p0, p1, p2, p3));
}
function log(uint p0, uint p1, string memory p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,uint,string,string)", p0, p1, p2, p3));
}
function log(uint p0, uint p1, string memory p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,uint,string,bool)", p0, p1, p2, p3));
}
function log(uint p0, uint p1, string memory p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,uint,string,address)", p0, p1, p2, p3));
}
function log(uint p0, uint p1, bool p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,uint,bool,uint)", p0, p1, p2, p3));
}
function log(uint p0, uint p1, bool p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,uint,bool,string)", p0, p1, p2, p3));
}
function log(uint p0, uint p1, bool p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,uint,bool,bool)", p0, p1, p2, p3));
}
function log(uint p0, uint p1, bool p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,uint,bool,address)", p0, p1, p2, p3));
}
function log(uint p0, uint p1, address p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,uint,address,uint)", p0, p1, p2, p3));
}
function log(uint p0, uint p1, address p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,uint,address,string)", p0, p1, p2, p3));
}
function log(uint p0, uint p1, address p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,uint,address,bool)", p0, p1, p2, p3));
}
function log(uint p0, uint p1, address p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,uint,address,address)", p0, p1, p2, p3));
}
function log(uint p0, string memory p1, uint p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,string,uint,uint)", p0, p1, p2, p3));
}
function log(uint p0, string memory p1, uint p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,string,uint,string)", p0, p1, p2, p3));
}
function log(uint p0, string memory p1, uint p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,string,uint,bool)", p0, p1, p2, p3));
}
function log(uint p0, string memory p1, uint p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,string,uint,address)", p0, p1, p2, p3));
}
function log(uint p0, string memory p1, string memory p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,string,string,uint)", p0, p1, p2, p3));
}
function log(uint p0, string memory p1, string memory p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,string,string,string)", p0, p1, p2, p3));
}
function log(uint p0, string memory p1, string memory p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,string,string,bool)", p0, p1, p2, p3));
}
function log(uint p0, string memory p1, string memory p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,string,string,address)", p0, p1, p2, p3));
}
function log(uint p0, string memory p1, bool p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,string,bool,uint)", p0, p1, p2, p3));
}
function log(uint p0, string memory p1, bool p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,string,bool,string)", p0, p1, p2, p3));
}
function log(uint p0, string memory p1, bool p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,string,bool,bool)", p0, p1, p2, p3));
}
function log(uint p0, string memory p1, bool p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,string,bool,address)", p0, p1, p2, p3));
}
function log(uint p0, string memory p1, address p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,string,address,uint)", p0, p1, p2, p3));
}
function log(uint p0, string memory p1, address p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,string,address,string)", p0, p1, p2, p3));
}
function log(uint p0, string memory p1, address p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,string,address,bool)", p0, p1, p2, p3));
}
function log(uint p0, string memory p1, address p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,string,address,address)", p0, p1, p2, p3));
}
function log(uint p0, bool p1, uint p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,bool,uint,uint)", p0, p1, p2, p3));
}
function log(uint p0, bool p1, uint p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,bool,uint,string)", p0, p1, p2, p3));
}
function log(uint p0, bool p1, uint p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,bool,uint,bool)", p0, p1, p2, p3));
}
function log(uint p0, bool p1, uint p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,bool,uint,address)", p0, p1, p2, p3));
}
function log(uint p0, bool p1, string memory p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,bool,string,uint)", p0, p1, p2, p3));
}
function log(uint p0, bool p1, string memory p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,bool,string,string)", p0, p1, p2, p3));
}
function log(uint p0, bool p1, string memory p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,bool,string,bool)", p0, p1, p2, p3));
}
function log(uint p0, bool p1, string memory p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,bool,string,address)", p0, p1, p2, p3));
}
function log(uint p0, bool p1, bool p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,bool,bool,uint)", p0, p1, p2, p3));
}
function log(uint p0, bool p1, bool p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,bool,bool,string)", p0, p1, p2, p3));
}
function log(uint p0, bool p1, bool p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,bool,bool,bool)", p0, p1, p2, p3));
}
function log(uint p0, bool p1, bool p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,bool,bool,address)", p0, p1, p2, p3));
}
function log(uint p0, bool p1, address p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,bool,address,uint)", p0, p1, p2, p3));
}
function log(uint p0, bool p1, address p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,bool,address,string)", p0, p1, p2, p3));
}
function log(uint p0, bool p1, address p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,bool,address,bool)", p0, p1, p2, p3));
}
function log(uint p0, bool p1, address p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,bool,address,address)", p0, p1, p2, p3));
}
function log(uint p0, address p1, uint p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,address,uint,uint)", p0, p1, p2, p3));
}
function log(uint p0, address p1, uint p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,address,uint,string)", p0, p1, p2, p3));
}
function log(uint p0, address p1, uint p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,address,uint,bool)", p0, p1, p2, p3));
}
function log(uint p0, address p1, uint p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,address,uint,address)", p0, p1, p2, p3));
}
function log(uint p0, address p1, string memory p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,address,string,uint)", p0, p1, p2, p3));
}
function log(uint p0, address p1, string memory p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,address,string,string)", p0, p1, p2, p3));
}
function log(uint p0, address p1, string memory p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,address,string,bool)", p0, p1, p2, p3));
}
function log(uint p0, address p1, string memory p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,address,string,address)", p0, p1, p2, p3));
}
function log(uint p0, address p1, bool p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,address,bool,uint)", p0, p1, p2, p3));
}
function log(uint p0, address p1, bool p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,address,bool,string)", p0, p1, p2, p3));
}
function log(uint p0, address p1, bool p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,address,bool,bool)", p0, p1, p2, p3));
}
function log(uint p0, address p1, bool p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,address,bool,address)", p0, p1, p2, p3));
}
function log(uint p0, address p1, address p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,address,address,uint)", p0, p1, p2, p3));
}
function log(uint p0, address p1, address p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,address,address,string)", p0, p1, p2, p3));
}
function log(uint p0, address p1, address p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,address,address,bool)", p0, p1, p2, p3));
}
function log(uint p0, address p1, address p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,address,address,address)", p0, p1, p2, p3));
}
function log(string memory p0, uint p1, uint p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,uint,uint,uint)", p0, p1, p2, p3));
}
function log(string memory p0, uint p1, uint p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,uint,uint,string)", p0, p1, p2, p3));
}
function log(string memory p0, uint p1, uint p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,uint,uint,bool)", p0, p1, p2, p3));
}
function log(string memory p0, uint p1, uint p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,uint,uint,address)", p0, p1, p2, p3));
}
function log(string memory p0, uint p1, string memory p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,uint,string,uint)", p0, p1, p2, p3));
}
function log(string memory p0, uint p1, string memory p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,uint,string,string)", p0, p1, p2, p3));
}
function log(string memory p0, uint p1, string memory p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,uint,string,bool)", p0, p1, p2, p3));
}
function log(string memory p0, uint p1, string memory p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,uint,string,address)", p0, p1, p2, p3));
}
function log(string memory p0, uint p1, bool p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,uint,bool,uint)", p0, p1, p2, p3));
}
function log(string memory p0, uint p1, bool p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,uint,bool,string)", p0, p1, p2, p3));
}
function log(string memory p0, uint p1, bool p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,uint,bool,bool)", p0, p1, p2, p3));
}
function log(string memory p0, uint p1, bool p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,uint,bool,address)", p0, p1, p2, p3));
}
function log(string memory p0, uint p1, address p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,uint,address,uint)", p0, p1, p2, p3));
}
function log(string memory p0, uint p1, address p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,uint,address,string)", p0, p1, p2, p3));
}
function log(string memory p0, uint p1, address p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,uint,address,bool)", p0, p1, p2, p3));
}
function log(string memory p0, uint p1, address p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,uint,address,address)", p0, p1, p2, p3));
}
function log(string memory p0, string memory p1, uint p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,string,uint,uint)", p0, p1, p2, p3));
}
function log(string memory p0, string memory p1, uint p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,string,uint,string)", p0, p1, p2, p3));
}
function log(string memory p0, string memory p1, uint p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,string,uint,bool)", p0, p1, p2, p3));
}
function log(string memory p0, string memory p1, uint p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,string,uint,address)", p0, p1, p2, p3));
}
function log(string memory p0, string memory p1, string memory p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,string,string,uint)", p0, p1, p2, p3));
}
function log(string memory p0, string memory p1, string memory p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,string,string,string)", p0, p1, p2, p3));
}
function log(string memory p0, string memory p1, string memory p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,string,string,bool)", p0, p1, p2, p3));
}
function log(string memory p0, string memory p1, string memory p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,string,string,address)", p0, p1, p2, p3));
}
function log(string memory p0, string memory p1, bool p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,string,bool,uint)", p0, p1, p2, p3));
}
function log(string memory p0, string memory p1, bool p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,string,bool,string)", p0, p1, p2, p3));
}
function log(string memory p0, string memory p1, bool p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,string,bool,bool)", p0, p1, p2, p3));
}
function log(string memory p0, string memory p1, bool p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,string,bool,address)", p0, p1, p2, p3));
}
function log(string memory p0, string memory p1, address p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,string,address,uint)", p0, p1, p2, p3));
}
function log(string memory p0, string memory p1, address p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,string,address,string)", p0, p1, p2, p3));
}
function log(string memory p0, string memory p1, address p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,string,address,bool)", p0, p1, p2, p3));
}
function log(string memory p0, string memory p1, address p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,string,address,address)", p0, p1, p2, p3));
}
function log(string memory p0, bool p1, uint p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,bool,uint,uint)", p0, p1, p2, p3));
}
function log(string memory p0, bool p1, uint p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,bool,uint,string)", p0, p1, p2, p3));
}
function log(string memory p0, bool p1, uint p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,bool,uint,bool)", p0, p1, p2, p3));
}
function log(string memory p0, bool p1, uint p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,bool,uint,address)", p0, p1, p2, p3));
}
function log(string memory p0, bool p1, string memory p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,bool,string,uint)", p0, p1, p2, p3));
}
function log(string memory p0, bool p1, string memory p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,bool,string,string)", p0, p1, p2, p3));
}
function log(string memory p0, bool p1, string memory p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,bool,string,bool)", p0, p1, p2, p3));
}
function log(string memory p0, bool p1, string memory p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,bool,string,address)", p0, p1, p2, p3));
}
function log(string memory p0, bool p1, bool p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,bool,bool,uint)", p0, p1, p2, p3));
}
function log(string memory p0, bool p1, bool p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,bool,bool,string)", p0, p1, p2, p3));
}
function log(string memory p0, bool p1, bool p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,bool,bool,bool)", p0, p1, p2, p3));
}
function log(string memory p0, bool p1, bool p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,bool,bool,address)", p0, p1, p2, p3));
}
function log(string memory p0, bool p1, address p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,bool,address,uint)", p0, p1, p2, p3));
}
function log(string memory p0, bool p1, address p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,bool,address,string)", p0, p1, p2, p3));
}
function log(string memory p0, bool p1, address p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,bool,address,bool)", p0, p1, p2, p3));
}
function log(string memory p0, bool p1, address p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,bool,address,address)", p0, p1, p2, p3));
}
function log(string memory p0, address p1, uint p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,address,uint,uint)", p0, p1, p2, p3));
}
function log(string memory p0, address p1, uint p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,address,uint,string)", p0, p1, p2, p3));
}
function log(string memory p0, address p1, uint p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,address,uint,bool)", p0, p1, p2, p3));
}
function log(string memory p0, address p1, uint p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,address,uint,address)", p0, p1, p2, p3));
}
function log(string memory p0, address p1, string memory p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,address,string,uint)", p0, p1, p2, p3));
}
function log(string memory p0, address p1, string memory p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,address,string,string)", p0, p1, p2, p3));
}
function log(string memory p0, address p1, string memory p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,address,string,bool)", p0, p1, p2, p3));
}
function log(string memory p0, address p1, string memory p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,address,string,address)", p0, p1, p2, p3));
}
function log(string memory p0, address p1, bool p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,address,bool,uint)", p0, p1, p2, p3));
}
function log(string memory p0, address p1, bool p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,address,bool,string)", p0, p1, p2, p3));
}
function log(string memory p0, address p1, bool p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,address,bool,bool)", p0, p1, p2, p3));
}
function log(string memory p0, address p1, bool p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,address,bool,address)", p0, p1, p2, p3));
}
function log(string memory p0, address p1, address p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,address,address,uint)", p0, p1, p2, p3));
}
function log(string memory p0, address p1, address p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,address,address,string)", p0, p1, p2, p3));
}
function log(string memory p0, address p1, address p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,address,address,bool)", p0, p1, p2, p3));
}
function log(string memory p0, address p1, address p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,address,address,address)", p0, p1, p2, p3));
}
function log(bool p0, uint p1, uint p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,uint,uint,uint)", p0, p1, p2, p3));
}
function log(bool p0, uint p1, uint p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,uint,uint,string)", p0, p1, p2, p3));
}
function log(bool p0, uint p1, uint p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,uint,uint,bool)", p0, p1, p2, p3));
}
function log(bool p0, uint p1, uint p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,uint,uint,address)", p0, p1, p2, p3));
}
function log(bool p0, uint p1, string memory p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,uint,string,uint)", p0, p1, p2, p3));
}
function log(bool p0, uint p1, string memory p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,uint,string,string)", p0, p1, p2, p3));
}
function log(bool p0, uint p1, string memory p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,uint,string,bool)", p0, p1, p2, p3));
}
function log(bool p0, uint p1, string memory p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,uint,string,address)", p0, p1, p2, p3));
}
function log(bool p0, uint p1, bool p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,uint,bool,uint)", p0, p1, p2, p3));
}
function log(bool p0, uint p1, bool p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,uint,bool,string)", p0, p1, p2, p3));
}
function log(bool p0, uint p1, bool p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,uint,bool,bool)", p0, p1, p2, p3));
}
function log(bool p0, uint p1, bool p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,uint,bool,address)", p0, p1, p2, p3));
}
function log(bool p0, uint p1, address p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,uint,address,uint)", p0, p1, p2, p3));
}
function log(bool p0, uint p1, address p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,uint,address,string)", p0, p1, p2, p3));
}
function log(bool p0, uint p1, address p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,uint,address,bool)", p0, p1, p2, p3));
}
function log(bool p0, uint p1, address p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,uint,address,address)", p0, p1, p2, p3));
}
function log(bool p0, string memory p1, uint p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,string,uint,uint)", p0, p1, p2, p3));
}
function log(bool p0, string memory p1, uint p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,string,uint,string)", p0, p1, p2, p3));
}
function log(bool p0, string memory p1, uint p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,string,uint,bool)", p0, p1, p2, p3));
}
function log(bool p0, string memory p1, uint p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,string,uint,address)", p0, p1, p2, p3));
}
function log(bool p0, string memory p1, string memory p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,string,string,uint)", p0, p1, p2, p3));
}
function log(bool p0, string memory p1, string memory p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,string,string,string)", p0, p1, p2, p3));
}
function log(bool p0, string memory p1, string memory p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,string,string,bool)", p0, p1, p2, p3));
}
function log(bool p0, string memory p1, string memory p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,string,string,address)", p0, p1, p2, p3));
}
function log(bool p0, string memory p1, bool p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,string,bool,uint)", p0, p1, p2, p3));
}
function log(bool p0, string memory p1, bool p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,string,bool,string)", p0, p1, p2, p3));
}
function log(bool p0, string memory p1, bool p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,string,bool,bool)", p0, p1, p2, p3));
}
function log(bool p0, string memory p1, bool p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,string,bool,address)", p0, p1, p2, p3));
}
function log(bool p0, string memory p1, address p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,string,address,uint)", p0, p1, p2, p3));
}
function log(bool p0, string memory p1, address p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,string,address,string)", p0, p1, p2, p3));
}
function log(bool p0, string memory p1, address p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,string,address,bool)", p0, p1, p2, p3));
}
function log(bool p0, string memory p1, address p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,string,address,address)", p0, p1, p2, p3));
}
function log(bool p0, bool p1, uint p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint,uint)", p0, p1, p2, p3));
}
function log(bool p0, bool p1, uint p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint,string)", p0, p1, p2, p3));
}
function log(bool p0, bool p1, uint p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint,bool)", p0, p1, p2, p3));
}
function log(bool p0, bool p1, uint p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint,address)", p0, p1, p2, p3));
}
function log(bool p0, bool p1, string memory p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,bool,string,uint)", p0, p1, p2, p3));
}
function log(bool p0, bool p1, string memory p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,bool,string,string)", p0, p1, p2, p3));
}
function log(bool p0, bool p1, string memory p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,bool,string,bool)", p0, p1, p2, p3));
}
function log(bool p0, bool p1, string memory p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,bool,string,address)", p0, p1, p2, p3));
}
function log(bool p0, bool p1, bool p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool,uint)", p0, p1, p2, p3));
}
function log(bool p0, bool p1, bool p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool,string)", p0, p1, p2, p3));
}
function log(bool p0, bool p1, bool p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool,bool)", p0, p1, p2, p3));
}
function log(bool p0, bool p1, bool p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool,address)", p0, p1, p2, p3));
}
function log(bool p0, bool p1, address p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,bool,address,uint)", p0, p1, p2, p3));
}
function log(bool p0, bool p1, address p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,bool,address,string)", p0, p1, p2, p3));
}
function log(bool p0, bool p1, address p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,bool,address,bool)", p0, p1, p2, p3));
}
function log(bool p0, bool p1, address p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,bool,address,address)", p0, p1, p2, p3));
}
function log(bool p0, address p1, uint p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,address,uint,uint)", p0, p1, p2, p3));
}
function log(bool p0, address p1, uint p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,address,uint,string)", p0, p1, p2, p3));
}
function log(bool p0, address p1, uint p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,address,uint,bool)", p0, p1, p2, p3));
}
function log(bool p0, address p1, uint p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,address,uint,address)", p0, p1, p2, p3));
}
function log(bool p0, address p1, string memory p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,address,string,uint)", p0, p1, p2, p3));
}
function log(bool p0, address p1, string memory p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,address,string,string)", p0, p1, p2, p3));
}
function log(bool p0, address p1, string memory p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,address,string,bool)", p0, p1, p2, p3));
}
function log(bool p0, address p1, string memory p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,address,string,address)", p0, p1, p2, p3));
}
function log(bool p0, address p1, bool p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,address,bool,uint)", p0, p1, p2, p3));
}
function log(bool p0, address p1, bool p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,address,bool,string)", p0, p1, p2, p3));
}
function log(bool p0, address p1, bool p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,address,bool,bool)", p0, p1, p2, p3));
}
function log(bool p0, address p1, bool p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,address,bool,address)", p0, p1, p2, p3));
}
function log(bool p0, address p1, address p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,address,address,uint)", p0, p1, p2, p3));
}
function log(bool p0, address p1, address p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,address,address,string)", p0, p1, p2, p3));
}
function log(bool p0, address p1, address p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,address,address,bool)", p0, p1, p2, p3));
}
function log(bool p0, address p1, address p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,address,address,address)", p0, p1, p2, p3));
}
function log(address p0, uint p1, uint p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,uint,uint,uint)", p0, p1, p2, p3));
}
function log(address p0, uint p1, uint p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,uint,uint,string)", p0, p1, p2, p3));
}
function log(address p0, uint p1, uint p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,uint,uint,bool)", p0, p1, p2, p3));
}
function log(address p0, uint p1, uint p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,uint,uint,address)", p0, p1, p2, p3));
}
function log(address p0, uint p1, string memory p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,uint,string,uint)", p0, p1, p2, p3));
}
function log(address p0, uint p1, string memory p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,uint,string,string)", p0, p1, p2, p3));
}
function log(address p0, uint p1, string memory p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,uint,string,bool)", p0, p1, p2, p3));
}
function log(address p0, uint p1, string memory p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,uint,string,address)", p0, p1, p2, p3));
}
function log(address p0, uint p1, bool p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,uint,bool,uint)", p0, p1, p2, p3));
}
function log(address p0, uint p1, bool p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,uint,bool,string)", p0, p1, p2, p3));
}
function log(address p0, uint p1, bool p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,uint,bool,bool)", p0, p1, p2, p3));
}
function log(address p0, uint p1, bool p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,uint,bool,address)", p0, p1, p2, p3));
}
function log(address p0, uint p1, address p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,uint,address,uint)", p0, p1, p2, p3));
}
function log(address p0, uint p1, address p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,uint,address,string)", p0, p1, p2, p3));
}
function log(address p0, uint p1, address p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,uint,address,bool)", p0, p1, p2, p3));
}
function log(address p0, uint p1, address p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,uint,address,address)", p0, p1, p2, p3));
}
function log(address p0, string memory p1, uint p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,string,uint,uint)", p0, p1, p2, p3));
}
function log(address p0, string memory p1, uint p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,string,uint,string)", p0, p1, p2, p3));
}
function log(address p0, string memory p1, uint p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,string,uint,bool)", p0, p1, p2, p3));
}
function log(address p0, string memory p1, uint p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,string,uint,address)", p0, p1, p2, p3));
}
function log(address p0, string memory p1, string memory p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,string,string,uint)", p0, p1, p2, p3));
}
function log(address p0, string memory p1, string memory p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,string,string,string)", p0, p1, p2, p3));
}
function log(address p0, string memory p1, string memory p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,string,string,bool)", p0, p1, p2, p3));
}
function log(address p0, string memory p1, string memory p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,string,string,address)", p0, p1, p2, p3));
}
function log(address p0, string memory p1, bool p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,string,bool,uint)", p0, p1, p2, p3));
}
function log(address p0, string memory p1, bool p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,string,bool,string)", p0, p1, p2, p3));
}
function log(address p0, string memory p1, bool p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,string,bool,bool)", p0, p1, p2, p3));
}
function log(address p0, string memory p1, bool p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,string,bool,address)", p0, p1, p2, p3));
}
function log(address p0, string memory p1, address p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,string,address,uint)", p0, p1, p2, p3));
}
function log(address p0, string memory p1, address p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,string,address,string)", p0, p1, p2, p3));
}
function log(address p0, string memory p1, address p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,string,address,bool)", p0, p1, p2, p3));
}
function log(address p0, string memory p1, address p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,string,address,address)", p0, p1, p2, p3));
}
function log(address p0, bool p1, uint p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,bool,uint,uint)", p0, p1, p2, p3));
}
function log(address p0, bool p1, uint p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,bool,uint,string)", p0, p1, p2, p3));
}
function log(address p0, bool p1, uint p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,bool,uint,bool)", p0, p1, p2, p3));
}
function log(address p0, bool p1, uint p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,bool,uint,address)", p0, p1, p2, p3));
}
function log(address p0, bool p1, string memory p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,bool,string,uint)", p0, p1, p2, p3));
}
function log(address p0, bool p1, string memory p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,bool,string,string)", p0, p1, p2, p3));
}
function log(address p0, bool p1, string memory p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,bool,string,bool)", p0, p1, p2, p3));
}
function log(address p0, bool p1, string memory p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,bool,string,address)", p0, p1, p2, p3));
}
function log(address p0, bool p1, bool p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,bool,bool,uint)", p0, p1, p2, p3));
}
function log(address p0, bool p1, bool p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,bool,bool,string)", p0, p1, p2, p3));
}
function log(address p0, bool p1, bool p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,bool,bool,bool)", p0, p1, p2, p3));
}
function log(address p0, bool p1, bool p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,bool,bool,address)", p0, p1, p2, p3));
}
function log(address p0, bool p1, address p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,bool,address,uint)", p0, p1, p2, p3));
}
function log(address p0, bool p1, address p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,bool,address,string)", p0, p1, p2, p3));
}
function log(address p0, bool p1, address p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,bool,address,bool)", p0, p1, p2, p3));
}
function log(address p0, bool p1, address p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,bool,address,address)", p0, p1, p2, p3));
}
function log(address p0, address p1, uint p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,address,uint,uint)", p0, p1, p2, p3));
}
function log(address p0, address p1, uint p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,address,uint,string)", p0, p1, p2, p3));
}
function log(address p0, address p1, uint p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,address,uint,bool)", p0, p1, p2, p3));
}
function log(address p0, address p1, uint p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,address,uint,address)", p0, p1, p2, p3));
}
function log(address p0, address p1, string memory p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,address,string,uint)", p0, p1, p2, p3));
}
function log(address p0, address p1, string memory p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,address,string,string)", p0, p1, p2, p3));
}
function log(address p0, address p1, string memory p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,address,string,bool)", p0, p1, p2, p3));
}
function log(address p0, address p1, string memory p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,address,string,address)", p0, p1, p2, p3));
}
function log(address p0, address p1, bool p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,address,bool,uint)", p0, p1, p2, p3));
}
function log(address p0, address p1, bool p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,address,bool,string)", p0, p1, p2, p3));
}
function log(address p0, address p1, bool p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,address,bool,bool)", p0, p1, p2, p3));
}
function log(address p0, address p1, bool p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,address,bool,address)", p0, p1, p2, p3));
}
function log(address p0, address p1, address p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,address,address,uint)", p0, p1, p2, p3));
}
function log(address p0, address p1, address p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,address,address,string)", p0, p1, p2, p3));
}
function log(address p0, address p1, address p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,address,address,bool)", p0, p1, p2, p3));
}
function log(address p0, address p1, address p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,address,address,address)", p0, p1, p2, p3));
}
}
/// @notice Modern and gas efficient ERC20 + EIP-2612 implementation.
/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/tokens/ERC20.sol)
/// @author Modified from Uniswap (https://github.com/Uniswap/uniswap-v2-core/blob/master/contracts/UniswapV2ERC20.sol)
/// @dev Do not manually set balances without updating totalSupply, as the sum of all user balances must not exceed it.
abstract contract ERC20 {
/*//////////////////////////////////////////////////////////////
EVENTS
//////////////////////////////////////////////////////////////*/
event Transfer(address indexed from, address indexed to, uint256 amount);
event Approval(address indexed owner, address indexed spender, uint256 amount);
/*//////////////////////////////////////////////////////////////
METADATA STORAGE
//////////////////////////////////////////////////////////////*/
string public name;
string public symbol;
uint8 public immutable decimals;
/*//////////////////////////////////////////////////////////////
ERC20 STORAGE
//////////////////////////////////////////////////////////////*/
uint256 public totalSupply;
mapping(address => uint256) public balanceOf;
mapping(address => mapping(address => uint256)) public allowance;
/*//////////////////////////////////////////////////////////////
EIP-2612 STORAGE
//////////////////////////////////////////////////////////////*/
uint256 internal immutable INITIAL_CHAIN_ID;
bytes32 internal immutable INITIAL_DOMAIN_SEPARATOR;
mapping(address => uint256) public nonces;
/*//////////////////////////////////////////////////////////////
CONSTRUCTOR
//////////////////////////////////////////////////////////////*/
constructor(
string memory _name,
string memory _symbol,
uint8 _decimals
) {
name = _name;
symbol = _symbol;
decimals = _decimals;
INITIAL_CHAIN_ID = block.chainid;
INITIAL_DOMAIN_SEPARATOR = computeDomainSeparator();
}
/*//////////////////////////////////////////////////////////////
ERC20 LOGIC
//////////////////////////////////////////////////////////////*/
function approve(address spender, uint256 amount) public virtual returns (bool) {
allowance[msg.sender][spender] = amount;
emit Approval(msg.sender, spender, amount);
return true;
}
function transfer(address to, uint256 amount) public virtual returns (bool) {
balanceOf[msg.sender] -= amount;
// Cannot overflow because the sum of all user
// balances can't exceed the max uint256 value.
unchecked {
balanceOf[to] += amount;
}
emit Transfer(msg.sender, to, amount);
return true;
}
function transferFrom(
address from,
address to,
uint256 amount
) public virtual returns (bool) {
uint256 allowed = allowance[from][msg.sender]; // Saves gas for limited approvals.
if (allowed != type(uint256).max) allowance[from][msg.sender] = allowed - amount;
balanceOf[from] -= amount;
// Cannot overflow because the sum of all user
// balances can't exceed the max uint256 value.
unchecked {
balanceOf[to] += amount;
}
emit Transfer(from, to, amount);
return true;
}
/*//////////////////////////////////////////////////////////////
EIP-2612 LOGIC
//////////////////////////////////////////////////////////////*/
function permit(
address owner,
address spender,
uint256 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) public virtual {
require(deadline >= block.timestamp, "PERMIT_DEADLINE_EXPIRED");
// Unchecked because the only math done is incrementing
// the owner's nonce which cannot realistically overflow.
unchecked {
address recoveredAddress = ecrecover(
keccak256(
abi.encodePacked(
"\x19\x01",
DOMAIN_SEPARATOR(),
keccak256(
abi.encode(
keccak256(
"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)"
),
owner,
spender,
value,
nonces[owner]++,
deadline
)
)
)
),
v,
r,
s
);
require(recoveredAddress != address(0) && recoveredAddress == owner, "INVALID_SIGNER");
allowance[recoveredAddress][spender] = value;
}
emit Approval(owner, spender, value);
}
function DOMAIN_SEPARATOR() public view virtual returns (bytes32) {
return block.chainid == INITIAL_CHAIN_ID ? INITIAL_DOMAIN_SEPARATOR : computeDomainSeparator();
}
function computeDomainSeparator() internal view virtual returns (bytes32) {
return
keccak256(
abi.encode(
keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"),
keccak256(bytes(name)),
keccak256("1"),
block.chainid,
address(this)
)
);
}
/*//////////////////////////////////////////////////////////////
INTERNAL MINT/BURN LOGIC
//////////////////////////////////////////////////////////////*/
function _mint(address to, uint256 amount) internal virtual {
totalSupply += amount;
// Cannot overflow because the sum of all user
// balances can't exceed the max uint256 value.
unchecked {
balanceOf[to] += amount;
}
emit Transfer(address(0), to, amount);
}
function _burn(address from, uint256 amount) internal virtual {
balanceOf[from] -= amount;
// Cannot underflow because a user's balance
// will never be larger than the total supply.
unchecked {
totalSupply -= amount;
}
emit Transfer(from, address(0), amount);
}
}
/// @notice Safe ETH and ERC20 transfer library that gracefully handles missing return values.
/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/SafeTransferLib.sol)
/// @dev Use with caution! Some functions in this library knowingly create dirty bits at the destination of the free memory pointer.
/// @dev Note that none of the functions in this library check that a token has code at all! That responsibility is delegated to the caller.
library SafeTransferLib {
/*//////////////////////////////////////////////////////////////
ETH OPERATIONS
//////////////////////////////////////////////////////////////*/
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)
}
require(success, "ETH_TRANSFER_FAILED");
}
/*//////////////////////////////////////////////////////////////
ERC20 OPERATIONS
//////////////////////////////////////////////////////////////*/
function safeTransferFrom(
ERC20 token,
address from,
address to,
uint256 amount
) internal {
bool success;
/// @solidity memory-safe-assembly
assembly {
// Get a pointer to some free memory.
let freeMemoryPointer := mload(0x40)
// Write the abi-encoded calldata into memory, beginning with the function selector.
mstore(freeMemoryPointer, 0x23b872dd00000000000000000000000000000000000000000000000000000000)
mstore(add(freeMemoryPointer, 4), from) // Append the "from" argument.
mstore(add(freeMemoryPointer, 36), to) // Append the "to" argument.
mstore(add(freeMemoryPointer, 68), amount) // Append the "amount" argument.
success := and(
// Set success to whether the call reverted, if not we check it either
// returned exactly 1 (can't just be non-zero data), or had no return data.
or(and(eq(mload(0), 1), gt(returndatasize(), 31)), iszero(returndatasize())),
// We use 100 because the length of our calldata totals up like so: 4 + 32 * 3.
// We use 0 and 32 to copy up to 32 bytes of return data into the scratch space.
// Counterintuitively, this call must be positioned second to the or() call in the
// surrounding and() call or else returndatasize() will be zero during the computation.
call(gas(), token, 0, freeMemoryPointer, 100, 0, 32)
)
}
require(success, "TRANSFER_FROM_FAILED");
}
function safeTransfer(
ERC20 token,
address to,
uint256 amount
) internal {
bool success;
/// @solidity memory-safe-assembly
assembly {
// Get a pointer to some free memory.
let freeMemoryPointer := mload(0x40)
// Write the abi-encoded calldata into memory, beginning with the function selector.
mstore(freeMemoryPointer, 0xa9059cbb00000000000000000000000000000000000000000000000000000000)
mstore(add(freeMemoryPointer, 4), to) // Append the "to" argument.
mstore(add(freeMemoryPointer, 36), amount) // Append the "amount" argument.
success := and(
// Set success to whether the call reverted, if not we check it either
// returned exactly 1 (can't just be non-zero data), or had no return data.
or(and(eq(mload(0), 1), gt(returndatasize(), 31)), iszero(returndatasize())),
// We use 68 because the length of our calldata totals up like so: 4 + 32 * 2.
// We use 0 and 32 to copy up to 32 bytes of return data into the scratch space.
// Counterintuitively, this call must be positioned second to the or() call in the
// surrounding and() call or else returndatasize() will be zero during the computation.
call(gas(), token, 0, freeMemoryPointer, 68, 0, 32)
)
}
require(success, "TRANSFER_FAILED");
}
function safeApprove(
ERC20 token,
address to,
uint256 amount
) internal {
bool success;
/// @solidity memory-safe-assembly
assembly {
// Get a pointer to some free memory.
let freeMemoryPointer := mload(0x40)
// Write the abi-encoded calldata into memory, beginning with the function selector.
mstore(freeMemoryPointer, 0x095ea7b300000000000000000000000000000000000000000000000000000000)
mstore(add(freeMemoryPointer, 4), to) // Append the "to" argument.
mstore(add(freeMemoryPointer, 36), amount) // Append the "amount" argument.
success := and(
// Set success to whether the call reverted, if not we check it either
// returned exactly 1 (can't just be non-zero data), or had no return data.
or(and(eq(mload(0), 1), gt(returndatasize(), 31)), iszero(returndatasize())),
// We use 68 because the length of our calldata totals up like so: 4 + 32 * 2.
// We use 0 and 32 to copy up to 32 bytes of return data into the scratch space.
// Counterintuitively, this call must be positioned second to the or() call in the
// surrounding and() call or else returndatasize() will be zero during the computation.
call(gas(), token, 0, freeMemoryPointer, 68, 0, 32)
)
}
require(success, "APPROVE_FAILED");
}
}
/// @notice Minimalist and modern Wrapped Ether implementation.
/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/tokens/WETH.sol)
/// @author Inspired by WETH9 (https://github.com/dapphub/ds-weth/blob/master/src/weth9.sol)
contract WETH is ERC20("Wrapped Ether", "WETH", 18) {
using SafeTransferLib for address;
event Deposit(address indexed from, uint256 amount);
event Withdrawal(address indexed to, uint256 amount);
function deposit() public payable virtual {
_mint(msg.sender, msg.value);
emit Deposit(msg.sender, msg.value);
}
function withdraw(uint256 amount) public virtual {
_burn(msg.sender, amount);
emit Withdrawal(msg.sender, amount);
msg.sender.safeTransferETH(amount);
}
receive() external payable virtual {
deposit();
}
}
/// https://etherscan.io/address/0xdf0770dF86a8034b3EFEf0A1Bb3c889B8332FF56#code
abstract contract LPTokenERC20 is ERC20 {
function amountLPtoLD(uint256 _lpAmount) external view virtual returns (uint256);
function totalLiquidity() external view virtual returns (uint256);
}
/// @dev
/// https://etherscan.io/address/0xB0D502E938ed5f4df2E681fE6E419ff29631d62b#code
/// basically a Goose MasterChef
interface ILPStaking {
function poolInfo(uint256 _pid)
external
view
returns (address lpToken, uint256 allocPoint, uint256 lastRewardBlock, uint256 accStargatePerShare);
function userInfo(uint256 _pid, address _address) external view returns (uint256 amount, uint256 rewardDebt);
function deposit(uint256 _pid, uint256 _amount) external;
function withdraw(uint256 _pid, uint256 _amount) external;
}
/// @dev https://etherscan.io/address/0x8731d54E9D02c286767d56ac03e8037C07e01e98#code
interface IStargateRouter {
struct lzTxObj {
uint256 dstGasForCall;
uint256 dstNativeAmount;
bytes dstNativeAddr;
}
function addLiquidity(uint256 _poolId, uint256 _amountLD, address _to) external;
function instantRedeemLocal(uint16 _srcPoolId, uint256 _amountLP, address _to) external returns (uint256);
function redeemLocal(
uint16 _dstChainId,
uint256 _srcPoolId,
uint256 _dstPoolId,
address payable _refundAddress,
uint256 _amountLP,
bytes calldata _to,
lzTxObj memory _lzTxParams
) external payable;
function callDelta(uint256 _poolId, bool _fullMode) external;
function quoteLayerZeroFee(
uint16 _dstChainId,
uint8 _functionType,
bytes calldata _toAddress,
bytes calldata _transferAndCallPayload,
lzTxObj memory _lzTxParams
) external view returns (uint256, uint256);
}
// https://github.com/Uniswap/swap-router-contracts/blob/main/contracts/interfaces/ISwapRouter02.sol
interface ISwapRouter02 {
function swapExactTokensForTokens(uint256 amountIn, uint256 amountOutMin, address[] calldata path, address to)
external
payable
returns (uint256 amountOut);
struct ExactInputSingleParams {
address tokenIn;
address tokenOut;
uint24 fee;
address recipient;
uint256 amountIn;
uint256 amountOutMinimum;
uint160 sqrtPriceLimitX96;
}
/// @notice Swaps `amountIn` of one token for as much as possible of another token
/// @dev Setting `amountIn` to 0 will cause the contract to look up its own balance,
/// and swap the entire amount, enabling contracts to send tokens before calling this function.
/// @param params The parameters necessary for the swap, encoded as `ExactInputSingleParams` in calldata
/// @return amountOut The amount of the received token
function exactInputSingle(ExactInputSingleParams calldata params) external payable returns (uint256 amountOut);
struct ExactInputParams {
bytes path;
address recipient;
uint256 amountIn;
uint256 amountOutMinimum;
}
/// @notice Swaps `amountIn` of one token for as much as possible of another along the specified path
/// @dev Setting `amountIn` to 0 will cause the contract to look up its own balance,
/// and swap the entire amount, enabling contracts to send tokens before calling this function.
/// @param params The parameters necessary for the multi-hop swap, encoded as `ExactInputParams` in calldata
/// @return amountOut The amount of the received token
function exactInput(ExactInputParams calldata params) external payable returns (uint256 amountOut);
}
// https://etherscan.io/address/0xd9e1ce17f2641f24ae83637ab66a2cca9c378b9f
// it's actually a UniswapV2Router02 but renamed for clarity vs actual uniswap
interface ISushiRouter {
function swapExactTokensForTokens(
uint256 amountIn,
uint256 amountOutMin,
address[] calldata path,
address to,
uint256 deadline
) external returns (uint256[] memory amounts);
function swapExactTokensForETH(
uint256 amountIn,
uint256 amountOutMin,
address[] calldata path,
address to,
uint256 deadline
) external returns (uint256[] memory amounts);
}
/// https://etherscan.io/address/0xBA12222222228d8Ba445958a75a0704d566BF2C8#code
interface IAsset {}
interface IVault {
struct JoinPoolRequest {
IAsset[] assets;
uint256[] maxAmountsIn;
bytes userData;
bool fromInternalBalance;
}
enum PoolSpecialization {
GENERAL,
MINIMAL_SWAP_INFO,
TWO_TOKEN
}
function getPool(bytes32 poolId) external view returns (address, PoolSpecialization);
function getPoolTokens(bytes32 poolId)
external
view
returns (address[] memory tokens, uint256[] memory balances, uint256 lastChangeBlock);
function getPoolTokenInfo(bytes32 poolId, address token)
external
view
returns (uint256 cash, uint256 managed, uint256 lastChangedBlock, address assetManager);
function queryExit(bytes32 poolId, address sender, address recipient, IVault.ExitPoolRequest memory request)
external
returns (uint256 bptIn, uint256[] memory amountsOut);
enum SwapKind {
GIVEN_IN,
GIVEN_OUT
}
struct BatchSwapStep {
bytes32 poolId;
uint256 assetInIndex;
uint256 assetOutIndex;
uint256 amount;
bytes userData;
}
struct FundManagement {
address sender;
bool fromInternalBalance;
address payable recipient;
bool toInternalBalance;
}
function batchSwap(
SwapKind kind,
BatchSwapStep[] memory swaps,
IAsset[] memory assets,
FundManagement memory funds,
int256[] memory limits,
uint256 deadline
) external payable returns (int256[] memory);
struct SingleSwap {
bytes32 poolId;
SwapKind kind;
IAsset assetIn;
IAsset assetOut;
uint256 amount;
bytes userData;
}
function swap(SingleSwap memory singleSwap, FundManagement memory funds, uint256 limit, uint256 deadline)
external
returns (uint256 amountCalculated);
function exitPool(bytes32 poolId, address sender, address payable recipient, ExitPoolRequest memory request)
external;
struct ExitPoolRequest {
IAsset[] assets;
uint256[] minAmountsOut;
bytes userData;
bool toInternalBalance;
}
}
abstract contract Ownable {
address public owner;
address public nominatedOwner;
error Unauthorized();
event OwnerChanged(address indexed previousOwner, address indexed newOwner);
constructor() {
owner = msg.sender;
}
// Public Functions
function acceptOwnership() external {
if (msg.sender != nominatedOwner) revert Unauthorized();
emit OwnerChanged(owner, msg.sender);
owner = msg.sender;
nominatedOwner = address(0);
}
// Restricted Functions: onlyOwner
/// @dev nominating zero address revokes a pending nomination
function nominateOwnership(address _newOwner) external onlyOwner {
nominatedOwner = _newOwner;
}
// Modifiers
modifier onlyOwner() {
if (msg.sender != owner) revert Unauthorized();
_;
}
}
// https://github.com/Uniswap/v3-periphery/blob/main/contracts/libraries/Path.sol
//https://github.com/GNSPS/solidity-bytes-utils/blob/master/contracts/BytesLib.sol
library BytesLib {
function slice(bytes memory _bytes, uint256 _start, uint256 _length) internal pure returns (bytes memory) {
require(_length + 31 >= _length, "slice_overflow");
require(_bytes.length >= _start + _length, "slice_outOfBounds");
bytes memory tempBytes;
assembly {
switch iszero(_length)
case 0 {
// Get a location of some free memory and store it in tempBytes as
// Solidity does for memory variables.
tempBytes := mload(0x40)
// The first word of the slice result is potentially a partial
// word read from the original array. To read it, we calculate
// the length of that partial word and start copying that many
// bytes into the array. The first word we copy will start with
// data we don't care about, but the last `lengthmod` bytes will
// land at the beginning of the contents of the new array. When
// we're done copying, we overwrite the full first word with
// the actual length of the slice.
let lengthmod := and(_length, 31)
// The multiplication in the next line is necessary
// because when slicing multiples of 32 bytes (lengthmod == 0)
// the following copy loop was copying the origin's length
// and then ending prematurely not copying everything it should.
let mc := add(add(tempBytes, lengthmod), mul(0x20, iszero(lengthmod)))
let end := add(mc, _length)
for {
// The multiplication in the next line has the same exact purpose
// as the one above.
let cc := add(add(add(_bytes, lengthmod), mul(0x20, iszero(lengthmod))), _start)
} lt(mc, end) {
mc := add(mc, 0x20)
cc := add(cc, 0x20)
} { mstore(mc, mload(cc)) }
mstore(tempBytes, _length)
//update free-memory pointer
//allocating the array padded to 32 bytes like the compiler does now
mstore(0x40, and(add(mc, 31), not(31)))
}
//if we want a zero-length slice let's just return a zero-length array
default {
tempBytes := mload(0x40)
//zero out the 32 bytes slice we are about to return
//we need to do it because Solidity does not garbage collect
mstore(tempBytes, 0)
mstore(0x40, add(tempBytes, 0x20))
}
}
return tempBytes;
}
function toAddress(bytes memory _bytes, uint256 _start) internal pure returns (address) {
require(_bytes.length >= _start + 20, "toAddress_outOfBounds");
address tempAddress;
assembly {
tempAddress := div(mload(add(add(_bytes, 0x20), _start)), 0x1000000000000000000000000)
}
return tempAddress;
}
function toUint24(bytes memory _bytes, uint256 _start) internal pure returns (uint24) {
require(_bytes.length >= _start + 3, "toUint24_outOfBounds");
uint24 tempUint;
assembly {
tempUint := mload(add(add(_bytes, 0x3), _start))
}
return tempUint;
}
}
/// @title Functions for manipulating path data for multihop swaps
library Path {
using BytesLib for bytes;
/// @dev The length of the bytes encoded address
uint256 private constant ADDR_SIZE = 20;
/// @dev The length of the bytes encoded fee
uint256 private constant FEE_SIZE = 3;
/// @dev The offset of a single token address and pool fee
uint256 private constant NEXT_OFFSET = ADDR_SIZE + FEE_SIZE;
/// @dev The offset of an encoded pool key
uint256 private constant POP_OFFSET = NEXT_OFFSET + ADDR_SIZE;
/// @dev The minimum length of an encoding that contains 2 or more pools
uint256 private constant MULTIPLE_POOLS_MIN_LENGTH = POP_OFFSET + NEXT_OFFSET;
/// @notice Returns true iff the path contains two or more pools
/// @param path The encoded swap path
/// @return True if path contains two or more pools, otherwise false
function hasMultiplePools(bytes memory path) internal pure returns (bool) {
return path.length >= MULTIPLE_POOLS_MIN_LENGTH;
}
/// @notice Returns the number of pools in the path
/// @param path The encoded swap path
/// @return The number of pools in the path
function numPools(bytes memory path) internal pure returns (uint256) {
// Ignore the first token address. From then on every fee and token offset indicates a pool.
return ((path.length - ADDR_SIZE) / NEXT_OFFSET);
}
/// @notice Decodes the first pool in path
/// @param path The bytes encoded swap path
/// @return tokenA The first token of the given pool
/// @return tokenB The second token of the given pool
/// @return fee The fee level of the pool
function decodeFirstPool(bytes memory path) internal pure returns (address tokenA, address tokenB, uint24 fee) {
tokenA = path.toAddress(0);
fee = path.toUint24(ADDR_SIZE);
tokenB = path.toAddress(NEXT_OFFSET);
}
/// @notice Gets the segment corresponding to the first pool in the path
/// @param path The bytes encoded swap path
/// @return The segment containing all data necessary to target the first pool in the path
function getFirstPool(bytes memory path) internal pure returns (bytes memory) {
return path.slice(0, POP_OFFSET);
}
/// @notice Skips a token + fee element from the buffer and returns the remainder
/// @param path The swap path
/// @return The remaining token + fee elements in the path
function skipToken(bytes memory path) internal pure returns (bytes memory) {
return path.slice(NEXT_OFFSET, path.length - NEXT_OFFSET);
}
}
/**
* @notice
* Swap contract used by strategies to:
* 1. swap strategy rewards to 'asset'
* 2. zap similar tokens to asset (e.g. USDT to USDC)
*/
contract Swap is Ownable {
using SafeTransferLib for ERC20;
using Path for bytes;
enum Route {
Unsupported,
UniswapV2,
UniswapV3Direct,
UniswapV3Path,
SushiSwap,
BalancerBatch,
BalancerSingle
}
/**
* @dev info depends on route:
* UniswapV2: address[] path
* UniswapV3Direct: uint24 fee
* UniswapV3Path: bytes path (address, uint24 fee, address, uint24 fee, address)
*/
struct RouteInfo {
Route route;
bytes info;
}
ISushiRouter internal constant sushiswap = ISushiRouter(0xd9e1cE17f2641f24aE83637ab66a2cca9C378B9F);
/// @dev single address which supports both uniswap v2 and v3 routes
ISwapRouter02 internal constant uniswap = ISwapRouter02(0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45);
IVault internal constant balancer = IVault(0xBA12222222228d8Ba445958a75a0704d566BF2C8);
/// @dev tokenIn => tokenOut => routeInfo
mapping(address => mapping(address => RouteInfo)) public routes;
/*//////////////////
/ Events /
//////////////////*/
event RouteSet(address indexed tokenIn, address indexed tokenOut, RouteInfo routeInfo);
event RouteRemoved(address indexed tokenIn, address indexed tokenOut);
/*//////////////////
/ Errors /
//////////////////*/
error UnsupportedRoute(address tokenIn, address tokenOut);
error InvalidRouteInfo();
constructor() Ownable() {
address CRV = 0xD533a949740bb3306d119CC777fa900bA034cd52;
address CVX = 0x4e3FBD56CD56c3e72c1403e103b45Db9da5B9D2B;
address LDO = 0x5A98FcBEA516Cf06857215779Fd812CA3beF1B32;
address WETH = 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2;
address STG = 0xAf5191B0De278C7286d6C7CC6ab6BB8A73bA2Cd6;
address USDC = 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48;
address USDT = 0xdAC17F958D2ee523a2206206994597C13D831ec7;
address BAL = 0xba100000625a3754423978a60c9317c58a424e3D;
address AURA = 0xC0c293ce456fF0ED870ADd98a0828Dd4d2903DBF;
_setRoute(CRV, WETH, RouteInfo({route: Route.UniswapV3Direct, info: abi.encode(uint24(3_000))}));
_setRoute(CVX, WETH, RouteInfo({route: Route.UniswapV3Direct, info: abi.encode(uint24(10_000))}));
_setRoute(LDO, WETH, RouteInfo({route: Route.UniswapV3Direct, info: abi.encode(uint24(3_000))}));
_setRoute(CRV, USDC, RouteInfo({route: Route.UniswapV3Direct, info: abi.encode(uint24(10_000))}));
_setRoute(
CVX,
USDC,
RouteInfo({route: Route.UniswapV3Path, info: abi.encodePacked(CVX, uint24(10_000), WETH, uint24(500), USDC)})
);
_setRoute(USDC, USDT, RouteInfo({route: Route.UniswapV3Direct, info: abi.encode(uint24(100))}));
_setRoute(
STG,
USDC,
RouteInfo({
route: Route.BalancerSingle,
info: abi.encode(0x3ff3a210e57cfe679d9ad1e9ba6453a716c56a2e0002000000000000000005d5)
})
);
IAsset[] memory stgWethAssets = new IAsset[](4);
stgWethAssets[0] = IAsset(STG);
stgWethAssets[1] = IAsset(USDC);
stgWethAssets[2] = IAsset(0x79c58f70905F734641735BC61e45c19dD9Ad60bC); // 3pool
stgWethAssets[3] = IAsset(WETH);
bytes32[] memory stgWethPoolIds = new bytes32[](3);
stgWethPoolIds[0] = 0x3ff3a210e57cfe679d9ad1e9ba6453a716c56a2e0002000000000000000005d5; // STG/USDC
stgWethPoolIds[1] = 0x79c58f70905f734641735bc61e45c19dd9ad60bc0000000000000000000004e7; // 3pool
stgWethPoolIds[2] = 0x08775ccb6674d6bdceb0797c364c2653ed84f3840002000000000000000004f0; // 3pool/WETH
IVault.BatchSwapStep[] memory stgWethSteps = _constructBalancerBatchSwapSteps(stgWethPoolIds);
_setRoute(STG, WETH, RouteInfo({route: Route.BalancerBatch, info: abi.encode(stgWethSteps, stgWethAssets)}));
bytes32 balWethPoolId = 0x5c6ee304399dbdb9c8ef030ab642b10820db8f56000200000000000000000014;
_setRoute(BAL, WETH, RouteInfo({route: Route.BalancerSingle, info: abi.encode(balWethPoolId)}));
bytes32 auraWethPoolId = 0xcfca23ca9ca720b6e98e3eb9b6aa0ffc4a5c08b9000200000000000000000274;
_setRoute(AURA, WETH, RouteInfo({route: Route.BalancerSingle, info: abi.encode(auraWethPoolId)}));
}
/*///////////////////////
/ Public View /
///////////////////////*/
function getRoute(address _tokenIn, address _tokenOut) external view returns (RouteInfo memory routeInfo) {
return routes[_tokenIn][_tokenOut];
}
/*////////////////////////////
/ Public Functions /
////////////////////////////*/
function swapTokens(address _tokenIn, address _tokenOut, uint256 _amount, uint256 _minReceived)
external
returns (uint256 received)
{
RouteInfo memory routeInfo = routes[_tokenIn][_tokenOut];
ERC20 tokenIn = ERC20(_tokenIn);
tokenIn.safeTransferFrom(msg.sender, address(this), _amount);
Route route = routeInfo.route;
bytes memory info = routeInfo.info;
if (route == Route.UniswapV2) {
received = _uniswapV2(_amount, _minReceived, info);
} else if (route == Route.UniswapV3Direct) {
received = _uniswapV3Direct(_tokenIn, _tokenOut, _amount, _minReceived, info);
} else if (route == Route.UniswapV3Path) {
received = _uniswapV3Path(_amount, _minReceived, info);
} else if (route == Route.SushiSwap) {
received = _sushiswap(_amount, _minReceived, info);
} else if (route == Route.BalancerBatch) {
received = _balancerBatch(_amount, _minReceived, info);
} else if (route == Route.BalancerSingle) {
received = _balancerSingle(_tokenIn, _tokenOut, _amount, _minReceived, info);
} else {
revert UnsupportedRoute(_tokenIn, _tokenOut);
}
// return unswapped amount to sender
uint256 balance = tokenIn.balanceOf(address(this));
if (balance > 0) tokenIn.safeTransfer(msg.sender, balance);
}
/*///////////////////////////////////////////
/ Restricted Functions: onlyOwner /
///////////////////////////////////////////*/
function setRoute(address _tokenIn, address _tokenOut, RouteInfo memory _routeInfo) external onlyOwner {
_setRoute(_tokenIn, _tokenOut, _routeInfo);
}
function unsetRoute(address _tokenIn, address _tokenOut) external onlyOwner {
delete routes[_tokenIn][_tokenOut];
emit RouteRemoved(_tokenIn, _tokenOut);
}
/*//////////////////////////////
/ Internal Functions /
//////////////////////////////*/
function _setRoute(address _tokenIn, address _tokenOut, RouteInfo memory _routeInfo) internal {
Route route = _routeInfo.route;
bytes memory info = _routeInfo.info;
if (route == Route.UniswapV2 || route == Route.SushiSwap) {
address[] memory path = abi.decode(info, (address[]));
if (path[0] != _tokenIn) revert InvalidRouteInfo();
if (path[path.length - 1] != _tokenOut) revert InvalidRouteInfo();
}
// just check that this doesn't throw an error
if (route == Route.UniswapV3Direct) abi.decode(info, (uint24));
if (route == Route.UniswapV3Path) {
bytes memory path = info;
// check first tokenIn
(address tokenIn,,) = path.decodeFirstPool();
if (tokenIn != _tokenIn) revert InvalidRouteInfo();
// check last tokenOut
while (path.hasMultiplePools()) path = path.skipToken();
(, address tokenOut,) = path.decodeFirstPool();
if (tokenOut != _tokenOut) revert InvalidRouteInfo();
}
// just check that these don't throw an error, i.e. the poolId contains both _tokenIn
if (route == Route.BalancerSingle) {
bytes32 poolId = abi.decode(info, (bytes32));
balancer.getPoolTokenInfo(poolId, _tokenIn);
balancer.getPoolTokenInfo(poolId, _tokenOut);
}
address router = _getRouterAddress(route);
ERC20(_tokenIn).safeApprove(router, 0);
ERC20(_tokenIn).safeApprove(router, type(uint256).max);
routes[_tokenIn][_tokenOut] = _routeInfo;
emit RouteSet(_tokenIn, _tokenOut, _routeInfo);
}
function _uniswapV2(uint256 _amount, uint256 _minReceived, bytes memory _path) internal returns (uint256) {
address[] memory path = abi.decode(_path, (address[]));
return uniswap.swapExactTokensForTokens(_amount, _minReceived, path, msg.sender);
}
function _sushiswap(uint256 _amount, uint256 _minReceived, bytes memory _path) internal returns (uint256) {
address[] memory path = abi.decode(_path, (address[]));
uint256[] memory received =
sushiswap.swapExactTokensForTokens(_amount, _minReceived, path, msg.sender, type(uint256).max);
return received[received.length - 1];
}
function _uniswapV3Direct(
address _tokenIn,
address _tokenOut,
uint256 _amount,
uint256 _minReceived,
bytes memory _info
) internal returns (uint256) {
uint24 fee = abi.decode(_info, (uint24));
return uniswap.exactInputSingle(
ISwapRouter02.ExactInputSingleParams({
tokenIn: _tokenIn,
tokenOut: _tokenOut,
fee: fee,
recipient: msg.sender,
amountIn: _amount,
amountOutMinimum: _minReceived,
sqrtPriceLimitX96: 0
})
);
}
function _uniswapV3Path(uint256 _amount, uint256 _minReceived, bytes memory _path) internal returns (uint256) {
return uniswap.exactInput(
ISwapRouter02.ExactInputParams({
path: _path,
recipient: msg.sender,
amountIn: _amount,
amountOutMinimum: _minReceived
})
);
}
function _balancerBatch(uint256 _amount, uint256 _minReceived, bytes memory _info) internal returns (uint256) {
(IVault.BatchSwapStep[] memory steps, IAsset[] memory assets) =
abi.decode(_info, (IVault.BatchSwapStep[], IAsset[]));
steps[0].amount = _amount;
int256[] memory limits = new int256[](assets.length);
limits[0] = int256(_amount);
limits[limits.length - 1] = -int256(_minReceived);
int256[] memory received = balancer.batchSwap(
IVault.SwapKind.GIVEN_IN,
steps,
assets,
IVault.FundManagement({
sender: address(this),
fromInternalBalance: false,
recipient: payable(address(msg.sender)),
toInternalBalance: false
}),
limits,
type(uint256).max
);
return uint256(-received[received.length - 1]);
}
function _balancerSingle(
address _tokenIn,
address _tokenOut,
uint256 _amount,
uint256 _minReceived,
bytes memory _info
) internal returns (uint256) {
bytes32 poolId = abi.decode(_info, (bytes32));
return balancer.swap(
IVault.SingleSwap({
poolId: poolId,
kind: IVault.SwapKind.GIVEN_IN,
assetIn: IAsset(_tokenIn),
assetOut: IAsset(_tokenOut),
amount: _amount,
userData: ""
}),
IVault.FundManagement({
sender: address(this),
fromInternalBalance: false,
recipient: payable(address(msg.sender)),
toInternalBalance: false
}),
_minReceived,
type(uint256).max
);
}
function _getRouterAddress(Route _route) internal pure returns (address) {
if (_route == Route.SushiSwap) {
return address(sushiswap);
} else if (_route == Route.UniswapV2 || _route == Route.UniswapV3Direct || _route == Route.UniswapV3Path) {
return address(uniswap);
} else if (_route == Route.BalancerBatch || _route == Route.BalancerSingle) {
return address(balancer);
} else {
revert InvalidRouteInfo();
}
}
function _constructBalancerBatchSwapSteps(bytes32[] memory _poolIds)
internal
pure
returns (IVault.BatchSwapStep[] memory steps)
{
uint256 length = _poolIds.length;
steps = new IVault.BatchSwapStep[](length);
for (uint8 i = 0; i < length; ++i) {
steps[i] = IVault.BatchSwapStep({
poolId: _poolIds[i],
assetInIndex: i,
assetOutIndex: i + 1,
amount: 0,
userData: ""
});
}
}
}
/// @notice Arithmetic library with operations for fixed-point numbers.
/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/FixedPointMathLib.sol)
/// @author Inspired by USM (https://github.com/usmfum/USM/blob/master/contracts/WadMath.sol)
library FixedPointMathLib {
/*//////////////////////////////////////////////////////////////
SIMPLIFIED FIXED POINT OPERATIONS
//////////////////////////////////////////////////////////////*/
uint256 internal constant MAX_UINT256 = 2**256 - 1;
uint256 internal constant WAD = 1e18; // The scalar of ETH and most ERC20s.
function mulWadDown(uint256 x, uint256 y) internal pure returns (uint256) {
return mulDivDown(x, y, WAD); // Equivalent to (x * y) / WAD rounded down.
}
function mulWadUp(uint256 x, uint256 y) internal pure returns (uint256) {
return mulDivUp(x, y, WAD); // Equivalent to (x * y) / WAD rounded up.
}
function divWadDown(uint256 x, uint256 y) internal pure returns (uint256) {
return mulDivDown(x, WAD, y); // Equivalent to (x * WAD) / y rounded down.
}
function divWadUp(uint256 x, uint256 y) internal pure returns (uint256) {
return mulDivUp(x, WAD, y); // Equivalent to (x * WAD) / y rounded up.
}
/*//////////////////////////////////////////////////////////////
LOW LEVEL FIXED POINT OPERATIONS
//////////////////////////////////////////////////////////////*/
function mulDivDown(
uint256 x,
uint256 y,
uint256 denominator
) internal pure returns (uint256 z) {
/// @solidity memory-safe-assembly
assembly {
// Equivalent to require(denominator != 0 && (y == 0 || x <= type(uint256).max / y))
if iszero(mul(denominator, iszero(mul(y, gt(x, div(MAX_UINT256, y)))))) {
revert(0, 0)
}
// Divide x * y by the denominator.
z := div(mul(x, y), denominator)
}
}
function mulDivUp(
uint256 x,
uint256 y,
uint256 denominator
) internal pure returns (uint256 z) {
/// @solidity memory-safe-assembly
assembly {
// Equivalent to require(denominator != 0 && (y == 0 || x <= type(uint256).max / y))
if iszero(mul(denominator, iszero(mul(y, gt(x, div(MAX_UINT256, y)))))) {
revert(0, 0)
}
// If x * y modulo the denominator is strictly greater than 0,
// 1 is added to round up the division of x * y by the denominator.
z := add(gt(mod(mul(x, y), denominator), 0), div(mul(x, y), denominator))
}
}
function rpow(
uint256 x,
uint256 n,
uint256 scalar
) internal pure returns (uint256 z) {
/// @solidity memory-safe-assembly
assembly {
switch x
case 0 {
switch n
case 0 {
// 0 ** 0 = 1
z := scalar
}
default {
// 0 ** n = 0
z := 0
}
}
default {
switch mod(n, 2)
case 0 {
// If n is even, store scalar in z for now.
z := scalar
}
default {
// If n is odd, store x in z for now.
z := x
}
// Shifting right by 1 is like dividing by 2.
let half := shr(1, scalar)
for {
// Shift n right by 1 before looping to halve it.
n := shr(1, n)
} n {
// Shift n right by 1 each iteration to halve it.
n := shr(1, n)
} {
// Revert immediately if x ** 2 would overflow.
// Equivalent to iszero(eq(div(xx, x), x)) here.
if shr(128, x) {
revert(0, 0)
}
// Store x squared.
let xx := mul(x, x)
// Round to the nearest number.
let xxRound := add(xx, half)
// Revert if xx + half overflowed.
if lt(xxRound, xx) {
revert(0, 0)
}
// Set x to scaled xxRound.
x := div(xxRound, scalar)
// If n is even:
if mod(n, 2) {
// Compute z * x.
let zx := mul(z, x)
// If z * x overflowed:
if iszero(eq(div(zx, x), z)) {
// Revert if x is non-zero.
if iszero(iszero(x)) {
revert(0, 0)
}
}
// Round to the nearest number.
let zxRound := add(zx, half)
// Revert if zx + half overflowed.
if lt(zxRound, zx) {
revert(0, 0)
}
// Return properly scaled zxRound.
z := div(zxRound, scalar)
}
}
}
}
}
/*//////////////////////////////////////////////////////////////
GENERAL NUMBER UTILITIES
//////////////////////////////////////////////////////////////*/
function sqrt(uint256 x) internal pure returns (uint256 z) {
/// @solidity memory-safe-assembly
assembly {
let y := x // We start y at x, which will help us make our initial estimate.
z := 181 // The "correct" value is 1, but this saves a multiplication later.
// This segment is to get a reasonable initial estimate for the Babylonian method. With a bad
// start, the correct # of bits increases ~linearly each iteration instead of ~quadratically.
// We check y >= 2^(k + 8) but shift right by k bits
// each branch to ensure that if x >= 256, then y >= 256.
if iszero(lt(y, 0x10000000000000000000000000000000000)) {
y := shr(128, y)
z := shl(64, z)
}
if iszero(lt(y, 0x1000000000000000000)) {
y := shr(64, y)
z := shl(32, z)
}
if iszero(lt(y, 0x10000000000)) {
y := shr(32, y)
z := shl(16, z)
}
if iszero(lt(y, 0x1000000)) {
y := shr(16, y)
z := shl(8, z)
}
// Goal was to get z*z*y within a small factor of x. More iterations could
// get y in a tighter range. Currently, we will have y in [256, 256*2^16).
// We ensured y >= 256 so that the relative difference between y and y+1 is small.
// That's not possible if x < 256 but we can just verify those cases exhaustively.
// Now, z*z*y <= x < z*z*(y+1), and y <= 2^(16+8), and either y >= 256, or x < 256.
// Correctness can be checked exhaustively for x < 256, so we assume y >= 256.
// Then z*sqrt(y) is within sqrt(257)/sqrt(256) of sqrt(x), or about 20bps.
// For s in the range [1/256, 256], the estimate f(s) = (181/1024) * (s+1) is in the range
// (1/2.84 * sqrt(s), 2.84 * sqrt(s)), with largest error when s = 1 and when s = 256 or 1/256.
// Since y is in [256, 256*2^16), let a = y/65536, so that a is in [1/256, 256). Then we can estimate
// sqrt(y) using sqrt(65536) * 181/1024 * (a + 1) = 181/4 * (y + 65536)/65536 = 181 * (y + 65536)/2^18.
// There is no overflow risk here since y < 2^136 after the first branch above.
z := shr(18, mul(z, add(y, 65536))) // A mul() is saved from starting z at 181.
// Given the worst case multiplicative error of 2.84 above, 7 iterations should be enough.
z := shr(1, add(z, div(x, z)))
z := shr(1, add(z, div(x, z)))
z := shr(1, add(z, div(x, z)))
z := shr(1, add(z, div(x, z)))
z := shr(1, add(z, div(x, z)))
z := shr(1, add(z, div(x, z)))
z := shr(1, add(z, div(x, z)))
// If x+1 is a perfect square, the Babylonian method cycles between
// floor(sqrt(x)) and ceil(sqrt(x)). This statement ensures we return floor.
// See: https://en.wikipedia.org/wiki/Integer_square_root#Using_only_integer_division
// Since the ceil is rare, we save gas on the assignment and repeat division in the rare case.
// If you don't care whether the floor or ceil square root is returned, you can remove this statement.
z := sub(z, lt(div(x, z), z))
}
}
function unsafeMod(uint256 x, uint256 y) internal pure returns (uint256 z) {
/// @solidity memory-safe-assembly
assembly {
// Mod x by y. Note this will return
// 0 instead of reverting if y is zero.
z := mod(x, y)
}
}
function unsafeDiv(uint256 x, uint256 y) internal pure returns (uint256 r) {
/// @solidity memory-safe-assembly
assembly {
// Divide x by y. Note this will return
// 0 instead of reverting if y is zero.
r := div(x, y)
}
}
function unsafeDivUp(uint256 x, uint256 y) internal pure returns (uint256 z) {
/// @solidity memory-safe-assembly
assembly {
// Add 1 to x * y if x % y > 0. Note this will
// return 0 instead of reverting if y is zero.
z := add(gt(mod(x, y), 0), div(x, y))
}
}
}
abstract contract Ownership {
address public owner;
address public nominatedOwner;
address public admin;
mapping(address => bool) public authorized;
event OwnerChanged(address indexed previousOwner, address indexed newOwner);
event AuthAdded(address indexed newAuth);
event AuthRemoved(address indexed oldAuth);
error Unauthorized();
error AlreadyRole();
error NotRole();
/// @param _authorized maximum of 256 addresses in constructor
constructor(address _nominatedOwner, address _admin, address[] memory _authorized) {
owner = msg.sender;
nominatedOwner = _nominatedOwner;
admin = _admin;
for (uint8 i = 0; i < _authorized.length; ++i) {
authorized[_authorized[i]] = true;
emit AuthAdded(_authorized[i]);
}
}
// Public Functions
function acceptOwnership() external {
if (msg.sender != nominatedOwner) revert Unauthorized();
emit OwnerChanged(owner, msg.sender);
owner = msg.sender;
nominatedOwner = address(0);
}
// Restricted Functions: onlyOwner
/// @dev nominating zero address revokes a pending nomination
function nominateOwnership(address _newOwner) external onlyOwner {
nominatedOwner = _newOwner;
}
function setAdmin(address _newAdmin) external onlyOwner {
if (admin == _newAdmin) revert AlreadyRole();
admin = _newAdmin;
}
// Restricted Functions: onlyAdmins
function addAuthorized(address _authorized) external onlyAdmins {
if (authorized[_authorized]) revert AlreadyRole();
authorized[_authorized] = true;
emit AuthAdded(_authorized);
}
function removeAuthorized(address _authorized) external onlyAdmins {
if (!authorized[_authorized]) revert NotRole();
authorized[_authorized] = false;
emit AuthRemoved(_authorized);
}
// Modifiers
modifier onlyOwner() {
if (msg.sender != owner) revert Unauthorized();
_;
}
modifier onlyAdmins() {
if (msg.sender != owner && msg.sender != admin) revert Unauthorized();
_;
}
modifier onlyAuthorized() {
if (msg.sender != owner && msg.sender != admin && !authorized[msg.sender]) revert Unauthorized();
_;
}
}
abstract contract BlockDelay {
/// @notice delay before functions with 'useBlockDelay' can be called by the same address
/// @dev 0 means no delay
uint256 public blockDelay;
uint256 internal constant MAX_BLOCK_DELAY = 10;
mapping(address => uint256) public lastBlock;
error AboveMaxBlockDelay();
error BeforeBlockDelay();
constructor(uint8 _delay) {
_setBlockDelay(_delay);
}
function _setBlockDelay(uint8 _newDelay) internal {
if (_newDelay > MAX_BLOCK_DELAY) revert AboveMaxBlockDelay();
blockDelay = _newDelay;
}
modifier useBlockDelay(address _address) {
if (block.number < lastBlock[_address] + blockDelay) revert BeforeBlockDelay();
lastBlock[_address] = block.number;
_;
}
}
/// @notice https://eips.ethereum.org/EIPS/eip-4626
interface IERC4626 {
event Deposit(address indexed caller, address indexed owner, uint256 assets, uint256 shares);
event Withdraw(
address indexed caller, address indexed receiver, address indexed owner, uint256 assets, uint256 shares
);
function asset() external view returns (ERC20);
function totalAssets() external view returns (uint256 assets);
function convertToShares(uint256 assets) external view returns (uint256 shares);
function convertToAssets(uint256 shares) external view returns (uint256 assets);
function maxDeposit(address receiver) external view returns (uint256 assets);
function previewDeposit(uint256 assets) external view returns (uint256 shares);
function deposit(uint256 assets, address receiver) external returns (uint256 shares);
function maxMint(address receiver) external view returns (uint256 shares);
function previewMint(uint256 shares) external view returns (uint256 assets);
function mint(uint256 shares, address receiver) external returns (uint256 assets);
function maxWithdraw(address owner) external view returns (uint256 assets);
function previewWithdraw(uint256 assets) external view returns (uint256 shares);
function withdraw(uint256 assets, address receiver, address owner) external returns (uint256 shares);
function maxRedeem(address owner) external view returns (uint256 shares);
function previewRedeem(uint256 shares) external view returns (uint256 assets);
function redeem(uint256 shares, address receiver, address owner) external returns (uint256 assets);
}
contract Vault is ERC20, IERC4626, Ownership, BlockDelay {
using SafeTransferLib for ERC20;
using FixedPointMathLib for uint256;
/// @notice token which the vault uses and accumulates
ERC20 public immutable asset;
/// @notice whether deposits and withdrawals are paused
bool public paused;
uint256 private _lockedProfit;
/// @notice timestamp of last report, used for locked profit calculations
uint256 public lastReport;
/// @notice period over which profits are gradually unlocked, defense against sandwich attacks
uint256 public lockedProfitDuration = 24 hours;
uint256 internal constant MAX_LOCKED_PROFIT_DURATION = 3 days;
/// @dev maximum user can deposit in a single tx
uint256 private _maxDeposit = type(uint256).max;
struct StrategyParams {
bool added;
uint256 debt;
uint256 debtRatio;
}
Strategy[] private _queue;
mapping(Strategy => StrategyParams) public strategies;
uint8 internal constant MAX_QUEUE_LENGTH = 20;
uint256 public totalDebt;
/// @dev proportion of funds kept in vault to facilitate user withdrawals
uint256 public floatDebtRatio;
uint256 public totalDebtRatio;
uint256 internal constant MAX_TOTAL_DEBT_RATIO = 1_000;
/*//////////////////
/ Events /
//////////////////*/
event Report(Strategy indexed strategy, uint256 harvested, uint256 gain, uint256 loss);
event Lend(Strategy indexed strategy, uint256 assets, uint256 slippage);
event Collect(Strategy indexed strategy, uint256 received, uint256 slippage, uint256 bonus);
event StrategyAdded(Strategy indexed strategy, uint256 debtRatio);
event StrategyDebtRatioChanged(Strategy indexed strategy, uint256 newDebtRatio);
event StrategyRemoved(Strategy indexed strategy);
event StrategyQueuePositionsSwapped(uint8 i, uint8 j, Strategy indexed newI, Strategy indexed newJ);
event LockedProfitDurationChanged(uint256 newDuration);
event MaxDepositChanged(uint256 newMaxDeposit);
event FloatDebtRatioChanged(uint256 newFloatDebtRatio);
/*//////////////////
/ Errors /
//////////////////*/
error Zero();
error BelowMinimum(uint256);
error AboveMaximum(uint256);
error AboveMaxDeposit();
error AlreadyStrategy();
error NotStrategy();
error StrategyDoesNotBelongToQueue();
error StrategyQueueFull();
error AlreadyValue();
error Paused();
/// @dev e.g. USDC becomes 'Unagii USD Coin Vault v3' and 'uUSDCv3'
constructor(
ERC20 _asset,
uint8 _blockDelay,
uint256 _floatDebtRatio,
address _nominatedOwner,
address _admin,
address[] memory _authorized
)
ERC20(
string(abi.encodePacked("Unagii ", _asset.name(), " Vault v3")),
string(abi.encodePacked("u", _asset.symbol(), "v3")),
_asset.decimals()
)
Ownership(_nominatedOwner, _admin, _authorized)
BlockDelay(_blockDelay)
{
asset = _asset;
_setFloatDebtRatio(_floatDebtRatio);
}
/*///////////////////////
/ Public View /
///////////////////////*/
function queue() external view returns (Strategy[] memory) {
return _queue;
}
function totalAssets() public view returns (uint256 assets) {
return asset.balanceOf(address(this)) + totalDebt;
}
function lockedProfit() public view returns (uint256 lockedAssets) {
uint256 last = lastReport;
uint256 duration = lockedProfitDuration;
unchecked {
// won't overflow since time is nowhere near uint256.max
if (block.timestamp >= last + duration) return 0;
// can overflow if _lockedProfit * difference > uint256.max but in practice should never happen
return _lockedProfit - _lockedProfit.mulDivDown(block.timestamp - last, duration);
}
}
function freeAssets() public view returns (uint256 assets) {
return totalAssets() - lockedProfit();
}
function convertToShares(uint256 _assets) public view returns (uint256 shares) {
uint256 supply = totalSupply;
return supply == 0 ? _assets : _assets.mulDivDown(supply, totalAssets());
}
function convertToAssets(uint256 _shares) public view returns (uint256 assets) {
uint256 supply = totalSupply;
return supply == 0 ? _shares : _shares.mulDivDown(totalAssets(), supply);
}
function maxDeposit(address) external view returns (uint256 assets) {
return _maxDeposit;
}
function previewDeposit(uint256 _assets) public view returns (uint256 shares) {
return convertToShares(_assets);
}
function maxMint(address) external view returns (uint256 shares) {
return convertToShares(_maxDeposit);
}
function previewMint(uint256 shares) public view returns (uint256 assets) {
uint256 supply = totalSupply;
return supply == 0 ? shares : shares.mulDivUp(totalAssets(), supply);
}
function maxWithdraw(address owner) external view returns (uint256 assets) {
return convertToAssets(balanceOf[owner]);
}
function previewWithdraw(uint256 assets) public view returns (uint256 shares) {
uint256 supply = totalSupply;
return supply == 0 ? assets : assets.mulDivUp(supply, freeAssets());
}
function maxRedeem(address _owner) external view returns (uint256 shares) {
return balanceOf[_owner];
}
function previewRedeem(uint256 shares) public view returns (uint256 assets) {
uint256 supply = totalSupply;
return supply == 0 ? shares : shares.mulDivDown(freeAssets(), supply);
}
/*////////////////////////////
/ Public Functions /
////////////////////////////*/
function safeDeposit(uint256 _assets, address _receiver, uint256 _minShares) external returns (uint256 shares) {
shares = deposit(_assets, _receiver);
if (shares < _minShares) revert BelowMinimum(shares);
}
function safeMint(uint256 _shares, address _receiver, uint256 _maxAssets) external returns (uint256 assets) {
assets = mint(_shares, _receiver);
if (assets > _maxAssets) revert AboveMaximum(assets);
}
function safeWithdraw(uint256 _assets, address _receiver, address _owner, uint256 _maxShares)
external
returns (uint256 shares)
{
shares = withdraw(_assets, _receiver, _owner);
if (shares > _maxShares) revert AboveMaximum(shares);
}
function safeRedeem(uint256 _shares, address _receiver, address _owner, uint256 _minAssets)
external
returns (uint256 assets)
{
assets = redeem(_shares, _receiver, _owner);
if (assets < _minAssets) revert BelowMinimum(assets);
}
/*////////////////////////////////////
/ ERC4626 Public Functions /
////////////////////////////////////*/
function deposit(uint256 _assets, address _receiver) public whenNotPaused returns (uint256 shares) {
if ((shares = previewDeposit(_assets)) == 0) revert Zero();
_deposit(_assets, shares, _receiver);
}
function mint(uint256 _shares, address _receiver) public whenNotPaused returns (uint256 assets) {
if (_shares == 0) revert Zero();
assets = previewMint(_shares);
_deposit(assets, _shares, _receiver);
}
function withdraw(uint256 _assets, address _receiver, address _owner) public returns (uint256 shares) {
if (_assets == 0) revert Zero();
shares = previewWithdraw(_assets);
_withdraw(_assets, shares, _owner, _receiver);
}
function redeem(uint256 _shares, address _receiver, address _owner) public returns (uint256 assets) {
if ((assets = previewRedeem(_shares)) == 0) revert Zero();
return _withdraw(assets, _shares, _owner, _receiver);
}
/*///////////////////////////////////////////
/ Restricted Functions: onlyOwner /
///////////////////////////////////////////*/
function addStrategy(Strategy _strategy, uint256 _debtRatio) external onlyOwner {
if (_strategy.vault() != this) revert StrategyDoesNotBelongToQueue();
if (strategies[_strategy].added) revert AlreadyStrategy();
if (_queue.length >= MAX_QUEUE_LENGTH) revert StrategyQueueFull();
totalDebtRatio += _debtRatio;
if (totalDebtRatio > MAX_TOTAL_DEBT_RATIO) revert AboveMaximum(totalDebtRatio);
strategies[_strategy] = StrategyParams({added: true, debt: 0, debtRatio: _debtRatio});
_queue.push(_strategy);
emit StrategyAdded(_strategy, _debtRatio);
}
/*////////////////////////////////////////////
/ Restricted Functions: onlyAdmins /
////////////////////////////////////////////*/
function removeStrategy(Strategy _strategy, bool _shouldHarvest, uint256 _minReceived)
external
onlyAdmins
returns (uint256 received)
{
if (!strategies[_strategy].added) revert NotStrategy();
_setDebtRatio(_strategy, 0);
uint256 balanceBefore = asset.balanceOf(address(this));
if (_shouldHarvest) _harvest(_strategy);
else _report(_strategy, 0);
received = asset.balanceOf(address(this)) - balanceBefore;
if (received < _minReceived) revert BelowMinimum(received);
// reorganize queue, filling in the empty strategy
Strategy[] memory newQueue = new Strategy[](_queue.length - 1);
bool found;
uint8 length = uint8(newQueue.length);
for (uint8 i = 0; i < length; ++i) {
if (_queue[i] == _strategy) found = true;
if (found) newQueue[i] = _queue[i + 1];
else newQueue[i] = _queue[i];
}
delete strategies[_strategy];
_queue = newQueue;
emit StrategyRemoved(_strategy);
}
function swapQueuePositions(uint8 _i, uint8 _j) external onlyAdmins {
Strategy s1 = _queue[_i];
Strategy s2 = _queue[_j];
_queue[_i] = s2;
_queue[_j] = s1;
emit StrategyQueuePositionsSwapped(_i, _j, s2, s1);
}
function setDebtRatio(Strategy _strategy, uint256 _newDebtRatio) external onlyAdmins {
if (!strategies[_strategy].added) revert NotStrategy();
_setDebtRatio(_strategy, _newDebtRatio);
}
/// @dev locked profit duration can be 0
function setLockedProfitDuration(uint256 _newDuration) external onlyAdmins {
if (_newDuration > MAX_LOCKED_PROFIT_DURATION) revert AboveMaximum(_newDuration);
if (_newDuration == lockedProfitDuration) revert AlreadyValue();
lockedProfitDuration = _newDuration;
emit LockedProfitDurationChanged(_newDuration);
}
function setBlockDelay(uint8 _newDelay) external onlyAdmins {
_setBlockDelay(_newDelay);
}
/*///////////////////////////////////////////////
/ Restricted Functions: onlyAuthorized /
///////////////////////////////////////////////*/
function suspendStrategy(Strategy _strategy) external onlyAuthorized {
if (!strategies[_strategy].added) revert NotStrategy();
_setDebtRatio(_strategy, 0);
}
function collectFromStrategy(Strategy _strategy, uint256 _assets, uint256 _minReceived)
external
onlyAuthorized
returns (uint256 received)
{
if (!strategies[_strategy].added) revert NotStrategy();
(received,) = _collect(_strategy, _assets, address(this));
if (received < _minReceived) revert BelowMinimum(received);
}
function pause() external onlyAuthorized {
if (paused) revert AlreadyValue();
paused = true;
}
function unpause() external onlyAuthorized {
if (!paused) revert AlreadyValue();
paused = false;
}
function setMaxDeposit(uint256 _newMaxDeposit) external onlyAuthorized {
if (_maxDeposit == _newMaxDeposit) revert AlreadyValue();
_maxDeposit = _newMaxDeposit;
emit MaxDepositChanged(_newMaxDeposit);
}
/// @dev costs less gas than multiple harvests if active strategies > 1
function harvestAll() external onlyAuthorized updateLastReport {
uint8 length = uint8(_queue.length);
for (uint8 i = 0; i < length; ++i) {
_harvest(_queue[i]);
}
}
/// @dev costs less gas than multiple reports if active strategies > 1
function reportAll() external onlyAuthorized updateLastReport {
uint8 length = uint8(_queue.length);
for (uint8 i = 0; i < length; ++i) {
_report(_queue[i], 0);
}
}
function harvest(Strategy _strategy) external onlyAuthorized updateLastReport {
if (!strategies[_strategy].added) revert NotStrategy();
_harvest(_strategy);
}
function report(Strategy _strategy) external onlyAuthorized updateLastReport {
if (!strategies[_strategy].added) revert NotStrategy();
_report(_strategy, 0);
}
function setFloatDebtRatio(uint256 _floatDebtRatio) external onlyAuthorized {
_setFloatDebtRatio(_floatDebtRatio);
}
/*///////////////////////////////////////////
/ Internal Override: useBlockDelay /
///////////////////////////////////////////*/
/// @dev address cannot mint/burn/send/receive share tokens on same block, defense against flash loan exploits
function _mint(address _to, uint256 _amount) internal override useBlockDelay(_to) {
if (_to == address(0)) revert Zero();
ERC20._mint(_to, _amount);
}
/// @dev address cannot mint/burn/send/receive share tokens on same block, defense against flash loan exploits
function _burn(address _from, uint256 _amount) internal override useBlockDelay(_from) {
ERC20._burn(_from, _amount);
}
/// @dev address cannot mint/burn/send/receive share tokens on same block, defense against flash loan exploits
function transfer(address _to, uint256 _amount)
public
override
useBlockDelay(msg.sender)
useBlockDelay(_to)
returns (bool)
{
return ERC20.transfer(_to, _amount);
}
/// @dev address cannot mint/burn/send/receive share tokens on same block, defense against flash loan exploits
function transferFrom(address _from, address _to, uint256 _amount)
public
override
useBlockDelay(_from)
useBlockDelay(_to)
returns (bool)
{
return ERC20.transferFrom(_from, _to, _amount);
}
/*//////////////////////////////
/ Internal Functions /
//////////////////////////////*/
function _deposit(uint256 _assets, uint256 _shares, address _receiver) internal {
if (_assets > _maxDeposit) revert AboveMaxDeposit();
asset.safeTransferFrom(msg.sender, address(this), _assets);
_mint(_receiver, _shares);
emit Deposit(msg.sender, _receiver, _assets, _shares);
}
function _withdraw(uint256 _assets, uint256 _shares, address _owner, address _receiver)
internal
returns (uint256 received)
{
if (msg.sender != _owner) {
uint256 allowed = allowance[_owner][msg.sender];
if (allowed != type(uint256).max) allowance[_owner][msg.sender] = allowed - _shares;
}
_burn(_owner, _shares);
emit Withdraw(msg.sender, _receiver, _owner, _assets, _shares);
// first, withdraw from balance
uint256 balance = asset.balanceOf(address(this));
if (balance > 0) {
uint256 amount = _assets > balance ? balance : _assets;
asset.safeTransfer(_receiver, amount);
_assets -= amount;
received += amount;
}
// next, withdraw from strategies
uint8 length = uint8(_queue.length);
for (uint8 i = 0; i < length; ++i) {
if (_assets == 0) break;
(uint256 receivedFromStrategy, uint256 slippage) = _collect(_queue[i], _assets, _receiver);
_assets -= receivedFromStrategy + slippage; // user pays for slippage, if any
received += receivedFromStrategy;
}
}
/// @dev do not touch debt outside of _lend(), _collect() and _report()
function _lend(Strategy _strategy, uint256 _assets) internal {
uint256 balance = asset.balanceOf(address(this));
uint256 amount = _assets > balance ? balance : _assets;
asset.safeTransfer(address(_strategy), amount);
_strategy.invest();
uint256 debtBefore = strategies[_strategy].debt;
uint256 debtAfter = _strategy.totalAssets();
uint256 diff = debtAfter - debtBefore;
uint256 slippage = amount > diff ? amount - diff : 0;
// ignore bonus if diff > amount, safeguard against imprecise `strategy.totalAsset()` calculations that open vault to being drained
uint256 debt = amount - slippage;
strategies[_strategy].debt += debt;
totalDebt += debt;
emit Lend(_strategy, amount, slippage);
}
function _collect(Strategy _strategy, uint256 _assets, address _receiver)
internal
returns (uint256 received, uint256 slippage)
{
uint256 bonus;
(received, slippage, bonus) = _strategy.withdraw(_assets);
uint256 total = received + slippage;
uint256 debt = strategies[_strategy].debt;
uint256 amount = debt > total ? received : total;
strategies[_strategy].debt -= amount;
totalDebt -= amount;
// do not pass bonuses on to users withdrawing, prevents exploits draining vault
if (_receiver == address(this)) emit Collect(_strategy, received, slippage, bonus);
else asset.safeTransfer(_receiver, received);
}
function _harvest(Strategy _strategy) internal {
_report(_strategy, _strategy.harvest());
}
/// @dev do not touch debt outside of _lend(), _collect() and _report()
function _report(Strategy _strategy, uint256 _harvested) internal {
uint256 assets = _strategy.totalAssets();
uint256 debt = strategies[_strategy].debt;
strategies[_strategy].debt = assets; // update debt
uint256 gain;
uint256 loss;
uint256 lockedProfitBefore = lockedProfit();
if (assets > debt) {
unchecked {
gain = assets - debt;
}
totalDebt += gain;
_lockedProfit = lockedProfitBefore + gain + _harvested;
} else if (debt > assets) {
unchecked {
loss = debt - assets;
totalDebt -= loss;
_lockedProfit = lockedProfitBefore + _harvested > loss ? lockedProfitBefore + _harvested - loss : 0;
}
}
uint256 possibleDebt =
totalDebtRatio == 0 ? 0 : totalAssets().mulDivDown(strategies[_strategy].debtRatio, totalDebtRatio);
if (possibleDebt > assets) _lend(_strategy, possibleDebt - assets);
else if (assets > possibleDebt) _collect(_strategy, assets - possibleDebt, address(this));
emit Report(_strategy, _harvested, gain, loss);
}
function _setDebtRatio(Strategy _strategy, uint256 _newDebtRatio) internal {
uint256 currentDebtRatio = strategies[_strategy].debtRatio;
if (_newDebtRatio == currentDebtRatio) revert AlreadyValue();
uint256 newTotalDebtRatio = totalDebtRatio + _newDebtRatio - currentDebtRatio;
if (newTotalDebtRatio > MAX_TOTAL_DEBT_RATIO) revert AboveMaximum(newTotalDebtRatio);
strategies[_strategy].debtRatio = _newDebtRatio;
totalDebtRatio = newTotalDebtRatio;
emit StrategyDebtRatioChanged(_strategy, _newDebtRatio);
}
function _setFloatDebtRatio(uint256 _floatDebtRatio) internal {
uint256 newTotalDebtRatio = totalDebtRatio + _floatDebtRatio - floatDebtRatio;
if (newTotalDebtRatio > MAX_TOTAL_DEBT_RATIO) revert AboveMaximum(newTotalDebtRatio);
floatDebtRatio = _floatDebtRatio;
totalDebtRatio = newTotalDebtRatio;
emit FloatDebtRatioChanged(_floatDebtRatio);
}
/*/////////////////////
/ Modifiers /
/////////////////////*/
modifier updateLastReport() {
_;
lastReport = block.timestamp;
}
modifier whenNotPaused() {
if (paused) revert Paused();
_;
}
}
/**
* @dev
* Strategies have to implement the following virtual functions:
*
* totalAssets()
* _withdraw(uint256, address)
* _harvest()
* _invest()
*/
abstract contract Strategy is Ownership {
using SafeTransferLib for ERC20;
using FixedPointMathLib for uint256;
Vault public immutable vault;
ERC20 public immutable asset;
/// @notice address which performance fees are sent to
address public treasury;
/// @notice performance fee sent to treasury / FEE_BASIS of 10_000
uint16 public fee = 1_000;
uint16 internal constant MAX_FEE = 1_000;
uint16 internal constant FEE_BASIS = 10_000;
/// @notice used to calculate slippage / SLIP_BASIS of 10_000
/// @dev default to 99% (or 1%)
uint16 public slip = 9_900;
uint16 internal constant SLIP_BASIS = 10_000;
/*//////////////////
/ Events /
//////////////////*/
event FeeChanged(uint16 newFee);
event SlipChanged(uint16 newSlip);
event TreasuryChanged(address indexed newTreasury);
/*//////////////////
/ Errors /
//////////////////*/
error Zero();
error NotVault();
error InvalidValue();
error AlreadyValue();
constructor(Vault _vault, address _treasury, address _nominatedOwner, address _admin, address[] memory _authorized)
Ownership(_nominatedOwner, _admin, _authorized)
{
vault = _vault;
asset = vault.asset();
treasury = _treasury;
}
/*//////////////////////////
/ Public Virtual /
//////////////////////////*/
/// @notice amount of 'asset' currently managed by strategy
function totalAssets() public view virtual returns (uint256);
/*///////////////////////////////////////////
/ Restricted Functions: onlyVault /
///////////////////////////////////////////*/
function withdraw(uint256 _assets) external onlyVault returns (uint256 received, uint256 slippage, uint256 bonus) {
uint256 total = totalAssets();
if (total == 0) revert Zero();
uint256 assets = _assets > total ? total : _assets;
received = _withdraw(assets);
unchecked {
if (assets > received) {
slippage = assets - received;
} else if (received > assets) {
bonus = received - assets;
// received cannot > assets for vault calcuations
received = assets;
}
}
}
/*//////////////////////////////////////////////////
/ Restricted Functions: onlyAdminOrVault /
//////////////////////////////////////////////////*/
function harvest() external onlyAdminOrVault returns (uint256 received) {
_harvest();
received = asset.balanceOf(address(this));
if (fee > 0) {
uint256 feeAmount = _calculateFee(received);
received -= feeAmount;
asset.safeTransfer(treasury, feeAmount);
}
asset.safeTransfer(address(vault), received);
}
function invest() external onlyAdminOrVault {
_invest();
}
/*///////////////////////////////////////////
/ Restricted Functions: onlyOwner /
///////////////////////////////////////////*/
function setFee(uint16 _fee) external onlyOwner {
if (_fee > MAX_FEE) revert InvalidValue();
if (_fee == fee) revert AlreadyValue();
fee = _fee;
emit FeeChanged(_fee);
}
function setTreasury(address _treasury) external onlyOwner {
if (_treasury == treasury) revert AlreadyValue();
treasury = _treasury;
emit TreasuryChanged(_treasury);
}
/*////////////////////////////////////////////
/ Restricted Functions: onlyAdmins /
////////////////////////////////////////////*/
function setSlip(uint16 _slip) external onlyAdmins {
if (_slip > SLIP_BASIS) revert InvalidValue();
if (_slip == slip) revert AlreadyValue();
slip = _slip;
emit SlipChanged(_slip);
}
/*////////////////////////////
/ Internal Virtual /
////////////////////////////*/
function _withdraw(uint256 _assets) internal virtual returns (uint256 received);
/// @dev return harvested assets
function _harvest() internal virtual;
function _invest() internal virtual;
/*//////////////////////////////
/ Internal Functions /
//////////////////////////////*/
function _calculateSlippage(uint256 _amount) internal view returns (uint256) {
return _amount.mulDivDown(slip, SLIP_BASIS);
}
function _calculateFee(uint256 _amount) internal view returns (uint256) {
return _amount.mulDivDown(fee, FEE_BASIS);
}
modifier onlyVault() {
if (msg.sender != address(vault)) revert NotVault();
_;
}
/*//////////////////////////////
/ Internal Functions /
//////////////////////////////*/
modifier onlyAdminOrVault() {
if (msg.sender != owner && msg.sender != admin && msg.sender != address(vault)) revert Unauthorized();
_;
}
}
contract WethStrategyStargate is Strategy {
using SafeTransferLib for ERC20;
using SafeTransferLib for LPTokenERC20;
using SafeTransferLib for WETH;
using FixedPointMathLib for uint256;
IStargateRouter internal constant router = IStargateRouter(0x8731d54E9D02c286767d56ac03e8037C07e01e98);
ILPStaking internal constant staking = ILPStaking(0xB0D502E938ed5f4df2E681fE6E419ff29631d62b);
ERC20 internal constant STG = ERC20(0xAf5191B0De278C7286d6C7CC6ab6BB8A73bA2Cd6);
/// @dev Stargate's version of WETH that automatically unwraps on transfer. Annoyingly, not canonical WETH
WETH internal constant SGETH = WETH(payable(0x72E2F4830b9E45d52F80aC08CB2bEC0FeF72eD9c));
/// @dev canonical WETH
WETH internal constant WETH9 = WETH(payable(0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2));
/// @dev pid of asset in their router
uint16 public constant routerPoolId = 13;
/// @dev pid of asset in their LP staking contract
uint256 public constant stakingPoolId = 2;
LPTokenERC20 public constant lpToken = LPTokenERC20(0x101816545F6bd2b1076434B54383a1E633390A2E);
/// @notice contract used to swap STG rewards to asset
Swap public swap;
/*///////////////
/ Errors /
///////////////*/
error NoRewards();
error NothingToInvest();
error BelowMinimum(uint256);
error InvalidAsset();
constructor(
Vault _vault,
address _treasury,
address _nominatedOwner,
address _admin,
address[] memory _authorized,
Swap _swap
) Strategy(_vault, _treasury, _nominatedOwner, _admin, _authorized) {
swap = _swap;
if (address(_vault.asset()) != address(WETH9)) revert InvalidAsset();
_approve();
}
receive() external payable {
if (msg.sender == address(WETH9)) return; // do nothing when unwrapping WETH
// SGETH automatically unwraps to ETH upon transfer in `redeemLocal` and `instantRedeemLocal`. We wrap and send
// WETH from other sources (namely router) to vault as ETH.
WETH9.deposit{value: msg.value}();
asset.safeTransfer(address(vault), msg.value);
}
/*///////////////////////
/ Public View /
///////////////////////*/
function totalAssets() public view override returns (uint256 assets) {
(uint256 stakedBalance,) = staking.userInfo(stakingPoolId, address(this));
return lpToken.amountLPtoLD(stakedBalance);
}
/*///////////////////////////////////////////
/ Restricted Functions: onlyOwner /
///////////////////////////////////////////*/
function changeSwap(Swap _swap) external onlyOwner {
_unapproveSwap();
swap = _swap;
_approveSwap();
}
/*////////////////////////////////////////////////
/ Restricted Functions: onlyAuthorized /
////////////////////////////////////////////////*/
function reapprove() external onlyAuthorized {
_unapprove();
_approve();
}
/**
* @notice Safeguard to manually withdraw if insufficient delta in Stargate local pool.
* @dev Use router.quoteLayerZeroFee to estimate 'msg.value' (excess will be refunded to `msg.sender`).
* @param _dstChainId STG chainId, see https://stargateprotocol.gitbook.io/stargate/developers/contract-addresses/mainnet, ideally we want to use the chain with cheapest gas
* @param _assets amount of LP to redeem, use type(uint256).max to withdraw everything
* @param _lzTxObj usually can just be (0, 0, "0x")
*/
function manualWithdraw(uint16 _dstChainId, uint256 _assets, IStargateRouter.lzTxObj calldata _lzTxObj)
external
payable
onlyAuthorized
{
uint256 assets = totalAssets();
uint256 amount = assets > _assets ? _assets : assets;
uint256 lpAmount = _convertAssetToLP(amount);
staking.withdraw(stakingPoolId, lpAmount);
router.redeemLocal{value: msg.value}(
_dstChainId,
routerPoolId,
routerPoolId,
payable(msg.sender),
lpAmount,
abi.encodePacked(address(this)),
_lzTxObj
);
}
/*/////////////////////////////
/ Internal Override /
/////////////////////////////*/
function _withdraw(uint256 _assets) internal override returns (uint256 received) {
uint256 lpAmount = _convertAssetToLP(_assets);
// lpAmount can round down to 0 which will cause the withdraw to fail
if (lpAmount == 0) return received;
// 1. withdraw from staking contract
staking.withdraw(stakingPoolId, lpAmount);
// withdraw from stargate router
received = router.instantRedeemLocal(routerPoolId, lpAmount, address(this));
if (received < _calculateSlippage(_assets)) revert BelowMinimum(received);
}
function _harvest() internal override {
// empty deposit/withdraw claims rewards withdraw as with all Goose clones
staking.withdraw(stakingPoolId, 0);
uint256 rewardBalance = STG.balanceOf(address(this));
if (rewardBalance == 0) revert NoRewards(); // nothing to harvest
swap.swapTokens(address(STG), address(asset), rewardBalance, 1);
}
function _invest() internal override {
uint256 assetBalance = asset.balanceOf(address(this));
if (assetBalance == 0) revert NothingToInvest();
WETH9.withdraw(assetBalance);
SGETH.deposit{value: assetBalance}();
router.addLiquidity(routerPoolId, assetBalance, address(this));
uint256 balance = lpToken.balanceOf(address(this));
if (balance < _calculateSlippage(assetBalance)) revert BelowMinimum(balance);
staking.deposit(stakingPoolId, balance);
}
/*//////////////////////////////
/ Internal Functions /
//////////////////////////////*/
function _approve() internal {
// approve deposit SGETH into router
SGETH.safeApprove(address(router), type(uint256).max);
// approve deposit lpToken into staking contract
lpToken.safeApprove(address(staking), type(uint256).max);
_approveSwap();
}
function _unapprove() internal {
SGETH.safeApprove(address(router), 0);
lpToken.safeApprove(address(staking), 0);
_unapproveSwap();
}
// approve swap rewards to asset
function _unapproveSwap() internal {
STG.safeApprove(address(swap), 0);
}
// approve swap rewards to asset
function _approveSwap() internal {
STG.safeApprove(address(swap), type(uint256).max);
}
function _convertAssetToLP(uint256 _amount) internal view returns (uint256) {
return _amount.mulDivDown(lpToken.totalSupply(), lpToken.totalLiquidity());
}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"contract Vault","name":"_vault","type":"address"},{"internalType":"address","name":"_treasury","type":"address"},{"internalType":"address","name":"_nominatedOwner","type":"address"},{"internalType":"address","name":"_admin","type":"address"},{"internalType":"address[]","name":"_authorized","type":"address[]"},{"internalType":"contract Swap","name":"_swap","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"AlreadyRole","type":"error"},{"inputs":[],"name":"AlreadyValue","type":"error"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"BelowMinimum","type":"error"},{"inputs":[],"name":"InvalidAsset","type":"error"},{"inputs":[],"name":"InvalidValue","type":"error"},{"inputs":[],"name":"NoRewards","type":"error"},{"inputs":[],"name":"NotRole","type":"error"},{"inputs":[],"name":"NotVault","type":"error"},{"inputs":[],"name":"NothingToInvest","type":"error"},{"inputs":[],"name":"Unauthorized","type":"error"},{"inputs":[],"name":"Zero","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"newAuth","type":"address"}],"name":"AuthAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"oldAuth","type":"address"}],"name":"AuthRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint16","name":"newFee","type":"uint16"}],"name":"FeeChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnerChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint16","name":"newSlip","type":"uint16"}],"name":"SlipChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"newTreasury","type":"address"}],"name":"TreasuryChanged","type":"event"},{"inputs":[],"name":"acceptOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_authorized","type":"address"}],"name":"addAuthorized","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"admin","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"asset","outputs":[{"internalType":"contract ERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"authorized","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract Swap","name":"_swap","type":"address"}],"name":"changeSwap","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"fee","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"harvest","outputs":[{"internalType":"uint256","name":"received","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"invest","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"lpToken","outputs":[{"internalType":"contract LPTokenERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"_dstChainId","type":"uint16"},{"internalType":"uint256","name":"_assets","type":"uint256"},{"components":[{"internalType":"uint256","name":"dstGasForCall","type":"uint256"},{"internalType":"uint256","name":"dstNativeAmount","type":"uint256"},{"internalType":"bytes","name":"dstNativeAddr","type":"bytes"}],"internalType":"struct IStargateRouter.lzTxObj","name":"_lzTxObj","type":"tuple"}],"name":"manualWithdraw","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"_newOwner","type":"address"}],"name":"nominateOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"nominatedOwner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"reapprove","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_authorized","type":"address"}],"name":"removeAuthorized","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"routerPoolId","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_newAdmin","type":"address"}],"name":"setAdmin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"_fee","type":"uint16"}],"name":"setFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"_slip","type":"uint16"}],"name":"setSlip","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_treasury","type":"address"}],"name":"setTreasury","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"slip","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"stakingPoolId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"swap","outputs":[{"internalType":"contract Swap","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalAssets","outputs":[{"internalType":"uint256","name":"assets","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"treasury","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"vault","outputs":[{"internalType":"contract Vault","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_assets","type":"uint256"}],"name":"withdraw","outputs":[{"internalType":"uint256","name":"received","type":"uint256"},{"internalType":"uint256","name":"slippage","type":"uint256"},{"internalType":"uint256","name":"bonus","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]Contract Creation Code
60c06040526004805463ffffffff60a01b19166304d5807d60a31b1790553480156200002a57600080fd5b5060405162002b6138038062002b618339810160408190526200004d916200047d565b60008054336001600160a01b03199182161782556001805482166001600160a01b038881169190911790915560028054909216908616179055869086908690869086908390839083905b81518160ff1610156200016957600160036000848460ff1681518110620000c257620000c2620005ba565b60200260200101516001600160a01b03166001600160a01b0316815260200190815260200160002060006101000a81548160ff021916908315150217905550818160ff1681518110620001195762000119620005ba565b60200260200101516001600160a01b03167f5daa78f70ec2227622bb7db0a1d9e750860491853de15431e1e473d305381c2160405160405180910390a26200016181620005d0565b905062000097565b505050506001600160a01b0385166080819052604080516338d52e0f60e01b815290516338d52e0f91600480820192602092909190829003018186803b158015620001b357600080fd5b505afa158015620001c8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620001ee9190620005ff565b6001600160a01b0390811660a052600480549582166001600160a01b031996871617815560058054898416971696909617909555604080516338d52e0f60e01b8152905173c02aaa39b223fe8d0a0e5c4f27ead9083c756cc29750918d16956338d52e0f955081810194506020935090829003018186803b1580156200027357600080fd5b505afa15801562000288573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620002ae9190620005ff565b6001600160a01b031614620002d657604051636448d6e960e11b815260040160405180910390fd5b620002e0620002ec565b50505050505062000626565b6200032f7372e2f4830b9e45d52f80ac08cb2bec0fef72ed9c738731d54e9d02c286767d56ac03e8037c07e01e986000196200037e602090811b6200160417901c565b6200037273101816545f6bd2b1076434b54383a1e633390a2e73b0d502e938ed5f4df2e681fe6e419ff29631d62b6000196200037e602090811b6200160417901c565b6200037c62000400565b565b600060405163095ea7b360e01b8152836004820152826024820152602060006044836000895af13d15601f3d1160016000511416171691505080620003fa5760405162461bcd60e51b815260206004820152600e60248201526d1054141493d59157d1905253115160921b604482015260640160405180910390fd5b50505050565b6005546200037c9073af5191b0de278c7286d6c7cc6ab6bb8a73ba2cd6906001600160a01b03166000196200037e602090811b6200160417901c565b6001600160a01b03811681146200045257600080fd5b50565b805162000462816200043c565b919050565b634e487b7160e01b600052604160045260246000fd5b60008060008060008060c087890312156200049757600080fd5b8651620004a4816200043c565b80965050602080880151620004b9816200043c565b6040890151909650620004cc816200043c565b6060890151909550620004df816200043c565b60808901519094506001600160401b0380821115620004fd57600080fd5b818a0191508a601f8301126200051257600080fd5b81518181111562000527576200052762000467565b8060051b604051601f19603f830116810181811085821117156200054f576200054f62000467565b60405291825284820192508381018501918d8311156200056e57600080fd5b938501935b828510156200059757620005878562000455565b8452938501939285019262000573565b809750505050505050620005ae60a0880162000455565b90509295509295509295565b634e487b7160e01b600052603260045260246000fd5b600060ff821660ff811415620005f657634e487b7160e01b600052601160045260246000fd5b60010192915050565b6000602082840312156200061257600080fd5b81516200061f816200043c565b9392505050565b60805160a0516124c862000699600039600081816102520152818161031901528181610bb001528181610c8401528181610cbc015281816119fc0152611da801526000818161027601528181610679015281816108ba01528181610b3a01528181610cde01526114e801526124c86000f3fe6080604052600436106101bb5760003560e01c80638da5cb5b116100ec578063d818f23a1161008a578063e8b5e51f11610064578063e8b5e51f14610612578063f0f4426014610627578063f851a44014610647578063fbfa77cf1461066757600080fd5b8063d818f23a146105aa578063d9380519146105bf578063ddca3f43146105df57600080fd5b8063a46c8505116100c6578063a46c850514610515578063b91816111461052a578063cf1c316a1461056a578063d59c58be1461058a57600080fd5b80638da5cb5b146104c05780638e005553146104e05780638fcb2be61461050057600080fd5b806353a47bb711610159578063704b6c0211610133578063704b6c0214610458578063793c85791461047857806379ba50971461048b5780638119c065146104a057600080fd5b806353a47bb7146103f05780635fcbd2851461041057806361d027b31461043857600080fd5b8063392c731f11610195578063392c731f1461035357806340cd23171461039b5780634641257d146103bb578063485d7d94146103d057600080fd5b806301e1d114146102a45780632e1a7d4d146102cc57806338d52e0f1461030757600080fd5b3661029f573373c02aaa39b223fe8d0a0e5c4f27ead9083c756cc214156101de57005b73c02aaa39b223fe8d0a0e5c4f27ead9083c756cc26001600160a01b031663d0e30db0346040518263ffffffff1660e01b81526004016000604051808303818588803b15801561022d57600080fd5b505af1158015610241573d6000803e3d6000fd5b5061029d9350506001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001691507f000000000000000000000000000000000000000000000000000000000000000090503461069b565b005b600080fd5b3480156102b057600080fd5b506102b961075f565b6040519081526020015b60405180910390f35b3480156102d857600080fd5b506102ec6102e73660046121ad565b6108ab565b604080519384526020840192909252908201526060016102c3565b34801561031357600080fd5b5061033b7f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020016102c3565b34801561035f57600080fd5b5060045461038890760100000000000000000000000000000000000000000000900461ffff1681565b60405161ffff90911681526020016102c3565b3480156103a757600080fd5b5061029d6103b63660046121dd565b61099d565b3480156103c757600080fd5b506102b9610b01565b3480156103dc57600080fd5b5061029d6103eb366004612214565b610d06565b3480156103fc57600080fd5b5060015461033b906001600160a01b031681565b34801561041c57600080fd5b5061033b73101816545f6bd2b1076434b54383a1e633390a2e81565b34801561044457600080fd5b5060045461033b906001600160a01b031681565b34801561046457600080fd5b5061029d610473366004612214565b610e02565b61029d610486366004612231565b610eae565b34801561049757600080fd5b5061029d611091565b3480156104ac57600080fd5b5060055461033b906001600160a01b031681565b3480156104cc57600080fd5b5060005461033b906001600160a01b031681565b3480156104ec57600080fd5b5061029d6104fb3660046121dd565b61112b565b34801561050c57600080fd5b50610388600d81565b34801561052157600080fd5b506102b9600281565b34801561053657600080fd5b5061055a610545366004612214565b60036020526000908152604090205460ff1681565b60405190151581526020016102c3565b34801561057657600080fd5b5061029d610585366004612214565b61126b565b34801561059657600080fd5b5061029d6105a5366004612214565b61136b565b3480156105b657600080fd5b5061029d6113db565b3480156105cb57600080fd5b5061029d6105da366004612214565b61144c565b3480156105eb57600080fd5b506004546103889074010000000000000000000000000000000000000000900461ffff1681565b34801561061e57600080fd5b5061029d6114b0565b34801561063357600080fd5b5061029d610642366004612214565b611530565b34801561065357600080fd5b5060025461033b906001600160a01b031681565b34801561067357600080fd5b5061033b7f000000000000000000000000000000000000000000000000000000000000000081565b60006040517fa9059cbb000000000000000000000000000000000000000000000000000000008152836004820152826024820152602060006044836000895af13d15601f3d1160016000511416171691505080610759576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600f60248201527f5452414e534645525f4641494c4544000000000000000000000000000000000060448201526064015b60405180910390fd5b50505050565b6040517f93f1a40b00000000000000000000000000000000000000000000000000000000815260026004820152306024820152600090819073b0d502e938ed5f4df2e681fe6e419ff29631d62b906393f1a40b90604401604080518083038186803b1580156107cd57600080fd5b505afa1580156107e1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610805919061228f565b506040517ff6cd35ee0000000000000000000000000000000000000000000000000000000081526004810182905290915073101816545f6bd2b1076434b54383a1e633390a2e9063f6cd35ee9060240160206040518083038186803b15801561086d57600080fd5b505afa158015610881573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108a591906122b3565b91505090565b60008080336001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614610911576040517f62df054500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061091b61075f565b905080610954576040517ff456040300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008186116109635785610965565b815b9050610970816116bd565b945084811115610984578481039350610994565b8085111561099457938490039150835b50509193909250565b6000546001600160a01b031633148015906109c357506002546001600160a01b03163314155b156109e0576040516282b42960e81b815260040160405180910390fd5b61271061ffff82161115610a20576040517faa7feadc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60045461ffff828116760100000000000000000000000000000000000000000000909204161415610a7d576040517fc4d933da00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600480547fffffffffffffffff0000ffffffffffffffffffffffffffffffffffffffffffff1676010000000000000000000000000000000000000000000061ffff8416908102919091179091556040519081527ffdb877bdd6097061fb8d18b884652721f0c42b47da21422277453d679c815e49906020015b60405180910390a150565b600080546001600160a01b03163314801590610b2857506002546001600160a01b03163314155b8015610b5d5750336001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614155b15610b7a576040516282b42960e81b815260040160405180910390fd5b610b82611853565b6040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a082319060240160206040518083038186803b158015610bfa57600080fd5b505afa158015610c0e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c3291906122b3565b60045490915074010000000000000000000000000000000000000000900461ffff1615610caf576000610c6482611a93565b9050610c7081836122cc565b600454909250610cad906001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811691168361069b565b505b610d036001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000167f00000000000000000000000000000000000000000000000000000000000000008361069b565b90565b6000546001600160a01b03163314801590610d2c57506002546001600160a01b03163314155b15610d49576040516282b42960e81b815260040160405180910390fd5b6001600160a01b03811660009081526003602052604090205460ff16610d9b576040517ffbb7077700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001600160a01b03811660008181526003602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055517fea160e8ad4e620d61f1d6fc4a3eedd36336ed4c5fa149bbd9db0beab48a945c19190a250565b6000546001600160a01b03163314610e2c576040516282b42960e81b815260040160405180910390fd5b6002546001600160a01b0382811691161415610e74576040517f0cf4f0b300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600280547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0392909216919091179055565b6000546001600160a01b03163314801590610ed457506002546001600160a01b03163314155b8015610ef057503360009081526003602052604090205460ff16155b15610f0d576040516282b42960e81b815260040160405180910390fd5b6000610f1761075f565b90506000838211610f285781610f2a565b835b90506000610f3782611ac9565b6040517f441a3e70000000000000000000000000000000000000000000000000000000008152600260048201526024810182905290915073b0d502e938ed5f4df2e681fe6e419ff29631d62b9063441a3e7090604401600060405180830381600087803b158015610fa757600080fd5b505af1158015610fbb573d6000803e3d6000fd5b50505050738731d54e9d02c286767d56ac03e8037c07e01e986001600160a01b0316638f2e1d183488600d80338730604051602001611025919060609190911b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016815260140190565b6040516020818303038152906040528c6040518963ffffffff1660e01b815260040161105797969594939291906123cc565b6000604051808303818588803b15801561107057600080fd5b505af1158015611084573d6000803e3d6000fd5b5050505050505050505050565b6001546001600160a01b031633146110bb576040516282b42960e81b815260040160405180910390fd5b6000805460405133926001600160a01b03909216917fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c91a3600080547fffffffffffffffffffffffff00000000000000000000000000000000000000009081163317909155600180549091169055565b6000546001600160a01b03163314611155576040516282b42960e81b815260040160405180910390fd5b6103e861ffff82161115611195576040517faa7feadc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60045461ffff828116740100000000000000000000000000000000000000009092041614156111f0576040517fc4d933da00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600480547fffffffffffffffffffff0000ffffffffffffffffffffffffffffffffffffffff167401000000000000000000000000000000000000000061ffff8416908102919091179091556040519081527f931a978d852c1b6fa9dd97300fd89c773ff625b91f697b0911e943ba15f9e24390602001610af6565b6000546001600160a01b0316331480159061129157506002546001600160a01b03163314155b156112ae576040516282b42960e81b815260040160405180910390fd5b6001600160a01b03811660009081526003602052604090205460ff1615611301576040517f0cf4f0b300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001600160a01b03811660008181526003602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055517f5daa78f70ec2227622bb7db0a1d9e750860491853de15431e1e473d305381c219190a250565b6000546001600160a01b03163314611395576040516282b42960e81b815260040160405180910390fd5b61139d611be0565b600580547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0383161790556113d8611c0d565b50565b6000546001600160a01b0316331480159061140157506002546001600160a01b03163314155b801561141d57503360009081526003602052604090205460ff16155b1561143a576040516282b42960e81b815260040160405180910390fd5b611442611c59565b61144a611cc9565b565b6000546001600160a01b03163314611476576040516282b42960e81b815260040160405180910390fd5b600180547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0392909216919091179055565b6000546001600160a01b031633148015906114d657506002546001600160a01b03163314155b801561150b5750336001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614155b15611528576040516282b42960e81b815260040160405180910390fd5b61144a611d77565b6000546001600160a01b0316331461155a576040516282b42960e81b815260040160405180910390fd5b6004546001600160a01b03828116911614156115a2576040517fc4d933da00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600480547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0383169081179091556040517fc714d22a2f08b695f81e7c707058db484aa5b4d6b4c9fd64beb10fe85832f60890600090a250565b60006040517f095ea7b3000000000000000000000000000000000000000000000000000000008152836004820152826024820152602060006044836000895af13d15601f3d1160016000511416171691505080610759576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f415050524f56455f4641494c45440000000000000000000000000000000000006044820152606401610750565b6000806116c983611ac9565b9050806116d65750919050565b6040517f441a3e70000000000000000000000000000000000000000000000000000000008152600260048201526024810182905273b0d502e938ed5f4df2e681fe6e419ff29631d62b9063441a3e7090604401600060405180830381600087803b15801561174357600080fd5b505af1158015611757573d6000803e3d6000fd5b50506040517fc4de93a5000000000000000000000000000000000000000000000000000000008152600d600482015260248101849052306044820152738731d54e9d02c286767d56ac03e8037c07e01e98925063c4de93a59150606401602060405180830381600087803b1580156117ce57600080fd5b505af11580156117e2573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061180691906122b3565b915061181183612143565b82101561184d576040517f06b2f1c700000000000000000000000000000000000000000000000000000000815260048101839052602401610750565b50919050565b6040517f441a3e70000000000000000000000000000000000000000000000000000000008152600260048201526000602482015273b0d502e938ed5f4df2e681fe6e419ff29631d62b9063441a3e7090604401600060405180830381600087803b1580156118c057600080fd5b505af11580156118d4573d6000803e3d6000fd5b50506040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201526000925073af5191b0de278c7286d6c7cc6ab6bb8a73ba2cd691506370a082319060240160206040518083038186803b15801561193e57600080fd5b505afa158015611952573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061197691906122b3565b9050806119af576040517f3fb087f400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6005546040517f8e18cdfc00000000000000000000000000000000000000000000000000000000815273af5191b0de278c7286d6c7cc6ab6bb8a73ba2cd660048201526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000081166024830152604482018490526001606483015290911690638e18cdfc90608401602060405180830381600087803b158015611a5757600080fd5b505af1158015611a6b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a8f91906122b3565b5050565b600454600090611ac390839074010000000000000000000000000000000000000000900461ffff16612710612171565b92915050565b6000611ac373101816545f6bd2b1076434b54383a1e633390a2e6001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b158015611b1b57600080fd5b505afa158015611b2f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b5391906122b3565b73101816545f6bd2b1076434b54383a1e633390a2e6001600160a01b03166315770f926040518163ffffffff1660e01b815260040160206040518083038186803b158015611ba057600080fd5b505afa158015611bb4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611bd891906122b3565b849190612171565b60055461144a9073af5191b0de278c7286d6c7cc6ab6bb8a73ba2cd6906001600160a01b03166000611604565b60055461144a9073af5191b0de278c7286d6c7cc6ab6bb8a73ba2cd6906001600160a01b03167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff611604565b611c8d7372e2f4830b9e45d52f80ac08cb2bec0fef72ed9c738731d54e9d02c286767d56ac03e8037c07e01e986000611604565b611cc173101816545f6bd2b1076434b54383a1e633390a2e73b0d502e938ed5f4df2e681fe6e419ff29631d62b6000611604565b61144a611be0565b611d1c7372e2f4830b9e45d52f80ac08cb2bec0fef72ed9c738731d54e9d02c286767d56ac03e8037c07e01e987fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff611604565b611d6f73101816545f6bd2b1076434b54383a1e633390a2e73b0d502e938ed5f4df2e681fe6e419ff29631d62b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff611604565b61144a611c0d565b6040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201526000907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a082319060240160206040518083038186803b158015611df257600080fd5b505afa158015611e06573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e2a91906122b3565b905080611e63576040517f3c652dfd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f2e1a7d4d0000000000000000000000000000000000000000000000000000000081526004810182905273c02aaa39b223fe8d0a0e5c4f27ead9083c756cc290632e1a7d4d90602401600060405180830381600087803b158015611ec957600080fd5b505af1158015611edd573d6000803e3d6000fd5b505050507372e2f4830b9e45d52f80ac08cb2bec0fef72ed9c6001600160a01b031663d0e30db0826040518263ffffffff1660e01b81526004016000604051808303818588803b158015611f3057600080fd5b505af1158015611f44573d6000803e3d6000fd5b50506040517f87b21efc000000000000000000000000000000000000000000000000000000008152600d600482015260248101859052306044820152738731d54e9d02c286767d56ac03e8037c07e01e9893506387b21efc92506064019050600060405180830381600087803b158015611fbd57600080fd5b505af1158015611fd1573d6000803e3d6000fd5b50506040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201526000925073101816545f6bd2b1076434b54383a1e633390a2e91506370a082319060240160206040518083038186803b15801561203b57600080fd5b505afa15801561204f573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061207391906122b3565b905061207e82612143565b8110156120ba576040517f06b2f1c700000000000000000000000000000000000000000000000000000000815260048101829052602401610750565b6040517fe2bbb158000000000000000000000000000000000000000000000000000000008152600260048201526024810182905273b0d502e938ed5f4df2e681fe6e419ff29631d62b9063e2bbb15890604401600060405180830381600087803b15801561212757600080fd5b505af115801561213b573d6000803e3d6000fd5b505050505050565b600454600090611ac3908390760100000000000000000000000000000000000000000000900461ffff166127105b6000827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04841183021582026121a657600080fd5b5091020490565b6000602082840312156121bf57600080fd5b5035919050565b803561ffff811681146121d857600080fd5b919050565b6000602082840312156121ef57600080fd5b6121f8826121c6565b9392505050565b6001600160a01b03811681146113d857600080fd5b60006020828403121561222657600080fd5b81356121f8816121ff565b60008060006060848603121561224657600080fd5b61224f846121c6565b925060208401359150604084013567ffffffffffffffff81111561227257600080fd5b84016060818703121561228457600080fd5b809150509250925092565b600080604083850312156122a257600080fd5b505080516020909101519092909150565b6000602082840312156122c557600080fd5b5051919050565b600082821015612305577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b500390565b8035825260208101356020830152600060408201357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe183360301811261234f57600080fd5b8201803567ffffffffffffffff81111561236857600080fd5b80360384131561237757600080fd5b606060408601528060608601528060208301608087013760006080828701015260807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8301168601019250505092915050565b600061ffff808a1683526020818a168185015281891660408501526001600160a01b038816606085015286608085015260e060a0850152855191508160e085015260005b8281101561242d5786810182015185820161010001528101612410565b8281111561244057600061010084870101525b5050601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016820182810361010090810160c08501526124838183018661230a565b9b9a505050505050505050505056fea2646970667358221220bc727841b2b053a7d6b8a974d8ae96afa0d2e60493a50c2cd966fd54d564cf9164736f6c634300080900330000000000000000000000006abe5f87e3f4dc87301064f63ca5b244d119980d0000000000000000000000001c064ea662365c09c8e87242791dacbb90002605000000000000000000000000e2ceda90aa1e43647ef306810a903b32c9a3aa94000000000000000000000000f4e2007bb865b78bc0eac0cc242e974efd49c06d00000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000df46950003eed5b40bd94fdf0efc4c148858eeb00000000000000000000000000000000000000000000000000000000000000030000000000000000000000000a1f3a2c20a7e8e4470ffa52c01646e1ff4c759a0000000000000000000000001c595009b331fe85fd658aa0b6b7be95b6921021000000000000000000000000beca7b566fad28ccbe6dce59d42d37768ab3cd8b
Deployed Bytecode
0x6080604052600436106101bb5760003560e01c80638da5cb5b116100ec578063d818f23a1161008a578063e8b5e51f11610064578063e8b5e51f14610612578063f0f4426014610627578063f851a44014610647578063fbfa77cf1461066757600080fd5b8063d818f23a146105aa578063d9380519146105bf578063ddca3f43146105df57600080fd5b8063a46c8505116100c6578063a46c850514610515578063b91816111461052a578063cf1c316a1461056a578063d59c58be1461058a57600080fd5b80638da5cb5b146104c05780638e005553146104e05780638fcb2be61461050057600080fd5b806353a47bb711610159578063704b6c0211610133578063704b6c0214610458578063793c85791461047857806379ba50971461048b5780638119c065146104a057600080fd5b806353a47bb7146103f05780635fcbd2851461041057806361d027b31461043857600080fd5b8063392c731f11610195578063392c731f1461035357806340cd23171461039b5780634641257d146103bb578063485d7d94146103d057600080fd5b806301e1d114146102a45780632e1a7d4d146102cc57806338d52e0f1461030757600080fd5b3661029f573373c02aaa39b223fe8d0a0e5c4f27ead9083c756cc214156101de57005b73c02aaa39b223fe8d0a0e5c4f27ead9083c756cc26001600160a01b031663d0e30db0346040518263ffffffff1660e01b81526004016000604051808303818588803b15801561022d57600080fd5b505af1158015610241573d6000803e3d6000fd5b5061029d9350506001600160a01b037f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc21691507f0000000000000000000000006abe5f87e3f4dc87301064f63ca5b244d119980d90503461069b565b005b600080fd5b3480156102b057600080fd5b506102b961075f565b6040519081526020015b60405180910390f35b3480156102d857600080fd5b506102ec6102e73660046121ad565b6108ab565b604080519384526020840192909252908201526060016102c3565b34801561031357600080fd5b5061033b7f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc281565b6040516001600160a01b0390911681526020016102c3565b34801561035f57600080fd5b5060045461038890760100000000000000000000000000000000000000000000900461ffff1681565b60405161ffff90911681526020016102c3565b3480156103a757600080fd5b5061029d6103b63660046121dd565b61099d565b3480156103c757600080fd5b506102b9610b01565b3480156103dc57600080fd5b5061029d6103eb366004612214565b610d06565b3480156103fc57600080fd5b5060015461033b906001600160a01b031681565b34801561041c57600080fd5b5061033b73101816545f6bd2b1076434b54383a1e633390a2e81565b34801561044457600080fd5b5060045461033b906001600160a01b031681565b34801561046457600080fd5b5061029d610473366004612214565b610e02565b61029d610486366004612231565b610eae565b34801561049757600080fd5b5061029d611091565b3480156104ac57600080fd5b5060055461033b906001600160a01b031681565b3480156104cc57600080fd5b5060005461033b906001600160a01b031681565b3480156104ec57600080fd5b5061029d6104fb3660046121dd565b61112b565b34801561050c57600080fd5b50610388600d81565b34801561052157600080fd5b506102b9600281565b34801561053657600080fd5b5061055a610545366004612214565b60036020526000908152604090205460ff1681565b60405190151581526020016102c3565b34801561057657600080fd5b5061029d610585366004612214565b61126b565b34801561059657600080fd5b5061029d6105a5366004612214565b61136b565b3480156105b657600080fd5b5061029d6113db565b3480156105cb57600080fd5b5061029d6105da366004612214565b61144c565b3480156105eb57600080fd5b506004546103889074010000000000000000000000000000000000000000900461ffff1681565b34801561061e57600080fd5b5061029d6114b0565b34801561063357600080fd5b5061029d610642366004612214565b611530565b34801561065357600080fd5b5060025461033b906001600160a01b031681565b34801561067357600080fd5b5061033b7f0000000000000000000000006abe5f87e3f4dc87301064f63ca5b244d119980d81565b60006040517fa9059cbb000000000000000000000000000000000000000000000000000000008152836004820152826024820152602060006044836000895af13d15601f3d1160016000511416171691505080610759576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600f60248201527f5452414e534645525f4641494c4544000000000000000000000000000000000060448201526064015b60405180910390fd5b50505050565b6040517f93f1a40b00000000000000000000000000000000000000000000000000000000815260026004820152306024820152600090819073b0d502e938ed5f4df2e681fe6e419ff29631d62b906393f1a40b90604401604080518083038186803b1580156107cd57600080fd5b505afa1580156107e1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610805919061228f565b506040517ff6cd35ee0000000000000000000000000000000000000000000000000000000081526004810182905290915073101816545f6bd2b1076434b54383a1e633390a2e9063f6cd35ee9060240160206040518083038186803b15801561086d57600080fd5b505afa158015610881573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108a591906122b3565b91505090565b60008080336001600160a01b037f0000000000000000000000006abe5f87e3f4dc87301064f63ca5b244d119980d1614610911576040517f62df054500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061091b61075f565b905080610954576040517ff456040300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008186116109635785610965565b815b9050610970816116bd565b945084811115610984578481039350610994565b8085111561099457938490039150835b50509193909250565b6000546001600160a01b031633148015906109c357506002546001600160a01b03163314155b156109e0576040516282b42960e81b815260040160405180910390fd5b61271061ffff82161115610a20576040517faa7feadc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60045461ffff828116760100000000000000000000000000000000000000000000909204161415610a7d576040517fc4d933da00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600480547fffffffffffffffff0000ffffffffffffffffffffffffffffffffffffffffffff1676010000000000000000000000000000000000000000000061ffff8416908102919091179091556040519081527ffdb877bdd6097061fb8d18b884652721f0c42b47da21422277453d679c815e49906020015b60405180910390a150565b600080546001600160a01b03163314801590610b2857506002546001600160a01b03163314155b8015610b5d5750336001600160a01b037f0000000000000000000000006abe5f87e3f4dc87301064f63ca5b244d119980d1614155b15610b7a576040516282b42960e81b815260040160405180910390fd5b610b82611853565b6040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201527f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc26001600160a01b0316906370a082319060240160206040518083038186803b158015610bfa57600080fd5b505afa158015610c0e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c3291906122b3565b60045490915074010000000000000000000000000000000000000000900461ffff1615610caf576000610c6482611a93565b9050610c7081836122cc565b600454909250610cad906001600160a01b037f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2811691168361069b565b505b610d036001600160a01b037f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2167f0000000000000000000000006abe5f87e3f4dc87301064f63ca5b244d119980d8361069b565b90565b6000546001600160a01b03163314801590610d2c57506002546001600160a01b03163314155b15610d49576040516282b42960e81b815260040160405180910390fd5b6001600160a01b03811660009081526003602052604090205460ff16610d9b576040517ffbb7077700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001600160a01b03811660008181526003602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055517fea160e8ad4e620d61f1d6fc4a3eedd36336ed4c5fa149bbd9db0beab48a945c19190a250565b6000546001600160a01b03163314610e2c576040516282b42960e81b815260040160405180910390fd5b6002546001600160a01b0382811691161415610e74576040517f0cf4f0b300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600280547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0392909216919091179055565b6000546001600160a01b03163314801590610ed457506002546001600160a01b03163314155b8015610ef057503360009081526003602052604090205460ff16155b15610f0d576040516282b42960e81b815260040160405180910390fd5b6000610f1761075f565b90506000838211610f285781610f2a565b835b90506000610f3782611ac9565b6040517f441a3e70000000000000000000000000000000000000000000000000000000008152600260048201526024810182905290915073b0d502e938ed5f4df2e681fe6e419ff29631d62b9063441a3e7090604401600060405180830381600087803b158015610fa757600080fd5b505af1158015610fbb573d6000803e3d6000fd5b50505050738731d54e9d02c286767d56ac03e8037c07e01e986001600160a01b0316638f2e1d183488600d80338730604051602001611025919060609190911b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016815260140190565b6040516020818303038152906040528c6040518963ffffffff1660e01b815260040161105797969594939291906123cc565b6000604051808303818588803b15801561107057600080fd5b505af1158015611084573d6000803e3d6000fd5b5050505050505050505050565b6001546001600160a01b031633146110bb576040516282b42960e81b815260040160405180910390fd5b6000805460405133926001600160a01b03909216917fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c91a3600080547fffffffffffffffffffffffff00000000000000000000000000000000000000009081163317909155600180549091169055565b6000546001600160a01b03163314611155576040516282b42960e81b815260040160405180910390fd5b6103e861ffff82161115611195576040517faa7feadc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60045461ffff828116740100000000000000000000000000000000000000009092041614156111f0576040517fc4d933da00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600480547fffffffffffffffffffff0000ffffffffffffffffffffffffffffffffffffffff167401000000000000000000000000000000000000000061ffff8416908102919091179091556040519081527f931a978d852c1b6fa9dd97300fd89c773ff625b91f697b0911e943ba15f9e24390602001610af6565b6000546001600160a01b0316331480159061129157506002546001600160a01b03163314155b156112ae576040516282b42960e81b815260040160405180910390fd5b6001600160a01b03811660009081526003602052604090205460ff1615611301576040517f0cf4f0b300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001600160a01b03811660008181526003602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055517f5daa78f70ec2227622bb7db0a1d9e750860491853de15431e1e473d305381c219190a250565b6000546001600160a01b03163314611395576040516282b42960e81b815260040160405180910390fd5b61139d611be0565b600580547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0383161790556113d8611c0d565b50565b6000546001600160a01b0316331480159061140157506002546001600160a01b03163314155b801561141d57503360009081526003602052604090205460ff16155b1561143a576040516282b42960e81b815260040160405180910390fd5b611442611c59565b61144a611cc9565b565b6000546001600160a01b03163314611476576040516282b42960e81b815260040160405180910390fd5b600180547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0392909216919091179055565b6000546001600160a01b031633148015906114d657506002546001600160a01b03163314155b801561150b5750336001600160a01b037f0000000000000000000000006abe5f87e3f4dc87301064f63ca5b244d119980d1614155b15611528576040516282b42960e81b815260040160405180910390fd5b61144a611d77565b6000546001600160a01b0316331461155a576040516282b42960e81b815260040160405180910390fd5b6004546001600160a01b03828116911614156115a2576040517fc4d933da00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600480547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0383169081179091556040517fc714d22a2f08b695f81e7c707058db484aa5b4d6b4c9fd64beb10fe85832f60890600090a250565b60006040517f095ea7b3000000000000000000000000000000000000000000000000000000008152836004820152826024820152602060006044836000895af13d15601f3d1160016000511416171691505080610759576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f415050524f56455f4641494c45440000000000000000000000000000000000006044820152606401610750565b6000806116c983611ac9565b9050806116d65750919050565b6040517f441a3e70000000000000000000000000000000000000000000000000000000008152600260048201526024810182905273b0d502e938ed5f4df2e681fe6e419ff29631d62b9063441a3e7090604401600060405180830381600087803b15801561174357600080fd5b505af1158015611757573d6000803e3d6000fd5b50506040517fc4de93a5000000000000000000000000000000000000000000000000000000008152600d600482015260248101849052306044820152738731d54e9d02c286767d56ac03e8037c07e01e98925063c4de93a59150606401602060405180830381600087803b1580156117ce57600080fd5b505af11580156117e2573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061180691906122b3565b915061181183612143565b82101561184d576040517f06b2f1c700000000000000000000000000000000000000000000000000000000815260048101839052602401610750565b50919050565b6040517f441a3e70000000000000000000000000000000000000000000000000000000008152600260048201526000602482015273b0d502e938ed5f4df2e681fe6e419ff29631d62b9063441a3e7090604401600060405180830381600087803b1580156118c057600080fd5b505af11580156118d4573d6000803e3d6000fd5b50506040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201526000925073af5191b0de278c7286d6c7cc6ab6bb8a73ba2cd691506370a082319060240160206040518083038186803b15801561193e57600080fd5b505afa158015611952573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061197691906122b3565b9050806119af576040517f3fb087f400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6005546040517f8e18cdfc00000000000000000000000000000000000000000000000000000000815273af5191b0de278c7286d6c7cc6ab6bb8a73ba2cd660048201526001600160a01b037f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc281166024830152604482018490526001606483015290911690638e18cdfc90608401602060405180830381600087803b158015611a5757600080fd5b505af1158015611a6b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a8f91906122b3565b5050565b600454600090611ac390839074010000000000000000000000000000000000000000900461ffff16612710612171565b92915050565b6000611ac373101816545f6bd2b1076434b54383a1e633390a2e6001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b158015611b1b57600080fd5b505afa158015611b2f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b5391906122b3565b73101816545f6bd2b1076434b54383a1e633390a2e6001600160a01b03166315770f926040518163ffffffff1660e01b815260040160206040518083038186803b158015611ba057600080fd5b505afa158015611bb4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611bd891906122b3565b849190612171565b60055461144a9073af5191b0de278c7286d6c7cc6ab6bb8a73ba2cd6906001600160a01b03166000611604565b60055461144a9073af5191b0de278c7286d6c7cc6ab6bb8a73ba2cd6906001600160a01b03167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff611604565b611c8d7372e2f4830b9e45d52f80ac08cb2bec0fef72ed9c738731d54e9d02c286767d56ac03e8037c07e01e986000611604565b611cc173101816545f6bd2b1076434b54383a1e633390a2e73b0d502e938ed5f4df2e681fe6e419ff29631d62b6000611604565b61144a611be0565b611d1c7372e2f4830b9e45d52f80ac08cb2bec0fef72ed9c738731d54e9d02c286767d56ac03e8037c07e01e987fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff611604565b611d6f73101816545f6bd2b1076434b54383a1e633390a2e73b0d502e938ed5f4df2e681fe6e419ff29631d62b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff611604565b61144a611c0d565b6040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201526000907f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc26001600160a01b0316906370a082319060240160206040518083038186803b158015611df257600080fd5b505afa158015611e06573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e2a91906122b3565b905080611e63576040517f3c652dfd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f2e1a7d4d0000000000000000000000000000000000000000000000000000000081526004810182905273c02aaa39b223fe8d0a0e5c4f27ead9083c756cc290632e1a7d4d90602401600060405180830381600087803b158015611ec957600080fd5b505af1158015611edd573d6000803e3d6000fd5b505050507372e2f4830b9e45d52f80ac08cb2bec0fef72ed9c6001600160a01b031663d0e30db0826040518263ffffffff1660e01b81526004016000604051808303818588803b158015611f3057600080fd5b505af1158015611f44573d6000803e3d6000fd5b50506040517f87b21efc000000000000000000000000000000000000000000000000000000008152600d600482015260248101859052306044820152738731d54e9d02c286767d56ac03e8037c07e01e9893506387b21efc92506064019050600060405180830381600087803b158015611fbd57600080fd5b505af1158015611fd1573d6000803e3d6000fd5b50506040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201526000925073101816545f6bd2b1076434b54383a1e633390a2e91506370a082319060240160206040518083038186803b15801561203b57600080fd5b505afa15801561204f573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061207391906122b3565b905061207e82612143565b8110156120ba576040517f06b2f1c700000000000000000000000000000000000000000000000000000000815260048101829052602401610750565b6040517fe2bbb158000000000000000000000000000000000000000000000000000000008152600260048201526024810182905273b0d502e938ed5f4df2e681fe6e419ff29631d62b9063e2bbb15890604401600060405180830381600087803b15801561212757600080fd5b505af115801561213b573d6000803e3d6000fd5b505050505050565b600454600090611ac3908390760100000000000000000000000000000000000000000000900461ffff166127105b6000827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04841183021582026121a657600080fd5b5091020490565b6000602082840312156121bf57600080fd5b5035919050565b803561ffff811681146121d857600080fd5b919050565b6000602082840312156121ef57600080fd5b6121f8826121c6565b9392505050565b6001600160a01b03811681146113d857600080fd5b60006020828403121561222657600080fd5b81356121f8816121ff565b60008060006060848603121561224657600080fd5b61224f846121c6565b925060208401359150604084013567ffffffffffffffff81111561227257600080fd5b84016060818703121561228457600080fd5b809150509250925092565b600080604083850312156122a257600080fd5b505080516020909101519092909150565b6000602082840312156122c557600080fd5b5051919050565b600082821015612305577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b500390565b8035825260208101356020830152600060408201357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe183360301811261234f57600080fd5b8201803567ffffffffffffffff81111561236857600080fd5b80360384131561237757600080fd5b606060408601528060608601528060208301608087013760006080828701015260807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8301168601019250505092915050565b600061ffff808a1683526020818a168185015281891660408501526001600160a01b038816606085015286608085015260e060a0850152855191508160e085015260005b8281101561242d5786810182015185820161010001528101612410565b8281111561244057600061010084870101525b5050601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016820182810361010090810160c08501526124838183018661230a565b9b9a505050505050505050505056fea2646970667358221220bc727841b2b053a7d6b8a974d8ae96afa0d2e60493a50c2cd966fd54d564cf9164736f6c63430008090033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000006abe5f87e3f4dc87301064f63ca5b244d119980d0000000000000000000000001c064ea662365c09c8e87242791dacbb90002605000000000000000000000000e2ceda90aa1e43647ef306810a903b32c9a3aa94000000000000000000000000f4e2007bb865b78bc0eac0cc242e974efd49c06d00000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000df46950003eed5b40bd94fdf0efc4c148858eeb00000000000000000000000000000000000000000000000000000000000000030000000000000000000000000a1f3a2c20a7e8e4470ffa52c01646e1ff4c759a0000000000000000000000001c595009b331fe85fd658aa0b6b7be95b6921021000000000000000000000000beca7b566fad28ccbe6dce59d42d37768ab3cd8b
-----Decoded View---------------
Arg [0] : _vault (address): 0x6aBE5f87E3F4dC87301064F63CA5b244d119980d
Arg [1] : _treasury (address): 0x1C064EA662365c09c8E87242791dAcbb90002605
Arg [2] : _nominatedOwner (address): 0xe2CEDA90aa1E43647EF306810a903b32c9a3Aa94
Arg [3] : _admin (address): 0xf4E2007bb865B78bc0EAc0cC242e974Efd49C06d
Arg [4] : _authorized (address[]): 0x0a1F3A2c20a7e8E4470fFA52c01646E1ff4c759A,0x1C595009B331fE85FD658aA0B6B7bE95B6921021,0xBeCA7b566FAd28cCbe6dcE59d42D37768Ab3CD8B
Arg [5] : _swap (address): 0x0df46950003EEd5b40bd94FDf0EFC4c148858eeB
-----Encoded View---------------
10 Constructor Arguments found :
Arg [0] : 0000000000000000000000006abe5f87e3f4dc87301064f63ca5b244d119980d
Arg [1] : 0000000000000000000000001c064ea662365c09c8e87242791dacbb90002605
Arg [2] : 000000000000000000000000e2ceda90aa1e43647ef306810a903b32c9a3aa94
Arg [3] : 000000000000000000000000f4e2007bb865b78bc0eac0cc242e974efd49c06d
Arg [4] : 00000000000000000000000000000000000000000000000000000000000000c0
Arg [5] : 0000000000000000000000000df46950003eed5b40bd94fdf0efc4c148858eeb
Arg [6] : 0000000000000000000000000000000000000000000000000000000000000003
Arg [7] : 0000000000000000000000000a1f3a2c20a7e8e4470ffa52c01646e1ff4c759a
Arg [8] : 0000000000000000000000001c595009b331fe85fd658aa0b6b7be95b6921021
Arg [9] : 000000000000000000000000beca7b566fad28ccbe6dce59d42d37768ab3cd8b
Deployed Bytecode Sourcemap
151079:7036:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;152933:10;151869:42;152933:28;152929:41;;;151079:7036;152929:41;151869:42;-1:-1:-1;;;;;153207:13:0;;153228:9;153207:33;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;153251:45:0;;-1:-1:-1;;;;;;;153251:5:0;:18;;-1:-1:-1;153278:5:0;;-1:-1:-1;153286:9:0;153251:18;:45::i;:::-;151079:7036;;;;;153407:214;;;;;;;;;;;;;:::i;:::-;;;160:25:1;;;148:2;133:18;153407:214:0;;;;;;;;147687:632;;;;;;;;;;-1:-1:-1;147687:632:0;;;;;:::i;:::-;;:::i;:::-;;;;583:25:1;;;639:2;624:18;;617:34;;;;667:18;;;660:34;571:2;556:18;147687:632:0;381:319:1;146097:28:0;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;883:55:1;;;865:74;;853:2;838:18;146097:28:0;705:240:1;146531:26:0;;;;;;;;;;-1:-1:-1;146531:26:0;;;;;;;;;;;;;;1124:6:1;1112:19;;;1094:38;;1082:2;1067:18;146531:26:0;950:188:1;149726:223:0;;;;;;;;;;-1:-1:-1;149726:223:0;;;;;:::i;:::-;;:::i;148503:397::-;;;;;;;;;;;;;:::i;121561:214::-;;;;;;;;;;-1:-1:-1;121561:214:0;;;;;:::i;:::-;;:::i;119857:29::-;;;;;;;;;;-1:-1:-1;119857:29:0;;;;-1:-1:-1;;;;;119857:29:0;;;152116:95;;;;;;;;;;;;152168:42;152116:95;;146194:23;;;;;;;;;;-1:-1:-1;146194:23:0;;;;-1:-1:-1;;;;;146194:23:0;;;121144:147;;;;;;;;;;-1:-1:-1;121144:147:0;;;;;:::i;:::-;;:::i;154753:657::-;;;;;;:::i;:::-;;:::i;120685:224::-;;;;;;;;;;;;;:::i;152280:16::-;;;;;;;;;;-1:-1:-1;152280:16:0;;;;-1:-1:-1;;;;;152280:16:0;;;119830:20;;;;;;;;;;-1:-1:-1;119830:20:0;;;;-1:-1:-1;;;;;119830:20:0;;;149143:210;;;;;;;;;;-1:-1:-1;149143:210:0;;;;;:::i;:::-;;:::i;151965:40::-;;;;;;;;;;;;152003:2;151965:40;;152068:41;;;;;;;;;;;;152108:1;152068:41;;119924:42;;;;;;;;;;-1:-1:-1;119924:42:0;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;3331:14:1;;3324:22;3306:41;;3294:2;3279:18;119924:42:0;3166:187:1;121342:211:0;;;;;;;;;;-1:-1:-1;121342:211:0;;;;;:::i;:::-;;:::i;153784:134::-;;;;;;;;;;-1:-1:-1;153784:134:0;;;;;:::i;:::-;;:::i;154096:97::-;;;;;;;;;;;;;:::i;121026:110::-;;;;;;;;;;-1:-1:-1;121026:110:0;;;;;:::i;:::-;;:::i;146296:25::-;;;;;;;;;;-1:-1:-1;146296:25:0;;;;;;;;;;;148908:72;;;;;;;;;;;;;:::i;149361:199::-;;;;;;;;;;-1:-1:-1;149361:199:0;;;;;:::i;:::-;;:::i;119895:20::-;;;;;;;;;;-1:-1:-1;119895:20:0;;;;-1:-1:-1;;;;;119895:20:0;;;146062:28;;;;;;;;;;;;;;;78070:1529;78187:12;78362:4;78356:11;78507:66;78488:17;78481:93;78622:2;78618:1;78599:17;78595:25;78588:37;78703:6;78698:2;78679:17;78675:26;78668:42;79515:2;79512:1;79508:2;79489:17;79486:1;79479:5;79472;79467:51;79031:16;79024:24;79018:2;79000:16;78997:24;78993:1;78989;78983:8;78980:15;78976:46;78973:76;78770:763;78759:774;;;79564:7;79556:35;;;;;;;4072:2:1;79556:35:0;;;4054:21:1;4111:2;4091:18;;;4084:30;4150:17;4130:18;;;4123:45;4185:18;;79556:35:0;;;;;;;;;78176:1423;78070:1529;;;:::o;153407:214::-;153514:46;;;;;152108:1;153514:46;;;4388:25:1;153554:4:0;4429:18:1;;;4422:83;153460:14:0;;;;151451:42;;153514:16;;4361:18:1;;153514:46:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;153578:35:0;;;;;;;;160:25:1;;;153487:73:0;;-1:-1:-1;152168:42:0;;153578:20;;133:18:1;;153578:35:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;153571:42;;;153407:214;:::o;147687:632::-;147750:16;;;150721:10;-1:-1:-1;;;;;150743:5:0;150721:28;;150717:51;;150758:10;;;;;;;;;;;;;;150717:51;147812:13:::1;147828;:11;:13::i;:::-;147812:29:::0;-1:-1:-1;147856:10:0;147852:29:::1;;147875:6;;;;;;;;;;;;;;147852:29;147894:14;147921:5;147911:7;:15;:33;;147937:7;147911:33;;;147929:5;147911:33;147894:50;;147968:17;147978:6;147968:9;:17::i;:::-;147957:28;;148036:8;148027:6;:17;148023:278;;;148085:8;148076:6;:17;148065:28;;148023:278;;;148130:6;148119:8;:17;148115:186;;;148176:6:::0;148165:17;;::::1;::::0;-1:-1:-1;148176:6:0;148115:186:::1;147801:518;;147687:632:::0;;;;;:::o;149726:223::-;121960:5;;-1:-1:-1;;;;;121960:5:0;121946:10;:19;;;;:42;;-1:-1:-1;121983:5:0;;-1:-1:-1;;;;;121983:5:0;121969:10;:19;;121946:42;121942:69;;;121997:14;;-1:-1:-1;;;121997:14:0;;;;;;;;;;;121942:69;146602:6:::1;149792:18;::::0;::::1;;149788:45;;;149819:14;;;;;;;;;;;;;;149788:45;149857:4;::::0;::::1;149848:13:::0;;::::1;149857:4:::0;;;::::1;;149848:13;149844:40;;;149870:14;;;;;;;;;;;;;;149844:40;149895:4;:12:::0;;;::::1;::::0;::::1;::::0;::::1;::::0;;::::1;::::0;;;::::1;::::0;;;149923:18:::1;::::0;1094:38:1;;;149923:18:0::1;::::0;1082:2:1;1067:18;149923::0::1;;;;;;;;149726:223:::0;:::o;148503:397::-;148557:16;150969:5;;-1:-1:-1;;;;;150969:5:0;150955:10;:19;;;;:42;;-1:-1:-1;150992:5:0;;-1:-1:-1;;;;;150992:5:0;150978:10;:19;;150955:42;:74;;;;-1:-1:-1;151001:10:0;-1:-1:-1;;;;;151023:5:0;151001:28;;;150955:74;150951:101;;;151038:14;;-1:-1:-1;;;151038:14:0;;;;;;;;;;;150951:101;148586:10:::1;:8;:10::i;:::-;148620:30;::::0;;;;148644:4:::1;148620:30;::::0;::::1;865:74:1::0;148620:5:0::1;-1:-1:-1::0;;;;;148620:15:0::1;::::0;::::1;::::0;838:18:1;;148620:30:0::1;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;148667:3;::::0;148609:41;;-1:-1:-1;148667:3:0;;::::1;;;:7:::0;148663:173:::1;;148691:17;148711:23;148725:8;148711:13;:23::i;:::-;148691:43:::0;-1:-1:-1;148749:21:0::1;148691:43:::0;148749:21;::::1;:::i;:::-;148804:8;::::0;148749:21;;-1:-1:-1;148785:39:0::1;::::0;-1:-1:-1;;;;;148785:5:0::1;:18:::0;::::1;::::0;148804:8:::1;148814:9:::0;148785:18:::1;:39::i;:::-;148676:160;148663:173;148848:44;-1:-1:-1::0;;;;;148848:5:0::1;:18;148875:5;148883:8:::0;148848:18:::1;:44::i;:::-;148503:397:::0;:::o;121561:214::-;121960:5;;-1:-1:-1;;;;;121960:5:0;121946:10;:19;;;;:42;;-1:-1:-1;121983:5:0;;-1:-1:-1;;;;;121983:5:0;121969:10;:19;;121946:42;121942:69;;;121997:14;;-1:-1:-1;;;121997:14:0;;;;;;;;;;;121942:69;-1:-1:-1;;;;;121644:23:0;::::1;;::::0;;;:10:::1;:23;::::0;;;;;::::1;;121639:46;;121676:9;;;;;;;;;;;;;;121639:46;-1:-1:-1::0;;;;;121696:23:0;::::1;121722:5;121696:23:::0;;;:10:::1;:23;::::0;;;;;:31;;;::::1;::::0;;121743:24;::::1;::::0;121722:5;121743:24:::1;121561:214:::0;:::o;121144:147::-;121853:5;;-1:-1:-1;;;;;121853:5:0;121839:10;:19;121835:46;;121867:14;;-1:-1:-1;;;121867:14:0;;;;;;;;;;;121835:46;121215:5:::1;::::0;-1:-1:-1;;;;;121215:18:0;;::::1;:5:::0;::::1;:18;121211:44;;;121242:13;;;;;;;;;;;;;;121211:44;121266:5;:17:::0;;;::::1;-1:-1:-1::0;;;;;121266:17:0;;;::::1;::::0;;;::::1;::::0;;121144:147::o;154753:657::-;122094:5;;-1:-1:-1;;;;;122094:5:0;122080:10;:19;;;;:42;;-1:-1:-1;122117:5:0;;-1:-1:-1;;;;;122117:5:0;122103:10;:19;;122080:42;:69;;;;-1:-1:-1;122138:10:0;122127:22;;;;:10;:22;;;;;;;;122126:23;122080:69;122076:96;;;122158:14;;-1:-1:-1;;;122158:14:0;;;;;;;;;;;122076:96;154932:14:::1;154949:13;:11;:13::i;:::-;154932:30;;154975:14;155001:7;154992:6;:16;:35;;155021:6;154992:35;;;155011:7;154992:35;154975:52;;155038:16;155057:25;155075:6;155057:17;:25::i;:::-;155095:41;::::0;;;;152108:1:::1;155095:41;::::0;::::1;5413:25:1::0;5454:18;;;5447:34;;;155038:44:0;;-1:-1:-1;151451:42:0::1;::::0;155095:16:::1;::::0;5386:18:1;;155095:41:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;151351:42;-1:-1:-1::0;;;;;155149:18:0::1;;155175:9;155200:11;152003:2;::::0;155288:10:::1;155314:8;155362:4;155337:31;;;;;;;5641:2:1::0;5637:15;;;;5654:66;5633:88;5621:101;;5747:2;5738:12;;5492:264;155337:31:0::1;;;;;;;;;;;;;155383:8;155149:253;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;154921:489;;;154753:657:::0;;;:::o;120685:224::-;120750:14;;-1:-1:-1;;;;;120750:14:0;120736:10;:28;120732:55;;120773:14;;-1:-1:-1;;;120773:14:0;;;;;;;;;;;120732:55;120816:5;;;120803:31;;120823:10;;-1:-1:-1;;;;;120816:5:0;;;;120803:31;;;120845:5;:18;;;;;;120853:10;120845:18;;;;;120874:27;;;;;;;120685:224::o;149143:210::-;121853:5;;-1:-1:-1;;;;;121853:5:0;121839:10;:19;121835:46;;121867:14;;-1:-1:-1;;;121867:14:0;;;;;;;;;;;121835:46;146363:5:::1;149206:14;::::0;::::1;;149202:41;;;149229:14;;;;;;;;;;;;;;149202:41;149266:3;::::0;::::1;149258:11:::0;;::::1;149266:3:::0;;;::::1;;149258:11;149254:38;;;149278:14;;;;;;;;;;;;;;149254:38;149303:3;:10:::0;;;::::1;::::0;::::1;::::0;::::1;::::0;;::::1;::::0;;;::::1;::::0;;;149329:16:::1;::::0;1094:38:1;;;149329:16:0::1;::::0;1082:2:1;1067:18;149329:16:0::1;950:188:1::0;121342:211:0;121960:5;;-1:-1:-1;;;;;121960:5:0;121946:10;:19;;;;:42;;-1:-1:-1;121983:5:0;;-1:-1:-1;;;;;121983:5:0;121969:10;:19;;121946:42;121942:69;;;121997:14;;-1:-1:-1;;;121997:14:0;;;;;;;;;;;121942:69;-1:-1:-1;;;;;121421:23:0;::::1;;::::0;;;:10:::1;:23;::::0;;;;;::::1;;121417:49;;;121453:13;;;;;;;;;;;;;;121417:49;-1:-1:-1::0;;;;;121477:23:0;::::1;;::::0;;;:10:::1;:23;::::0;;;;;:30;;;::::1;121503:4;121477:30;::::0;;121523:22;::::1;::::0;121477:23;121523:22:::1;121342:211:::0;:::o;153784:134::-;121853:5;;-1:-1:-1;;;;;121853:5:0;121839:10;:19;121835:46;;121867:14;;-1:-1:-1;;;121867:14:0;;;;;;;;;;;121835:46;153846:16:::1;:14;:16::i;:::-;153873:4;:12:::0;;;::::1;-1:-1:-1::0;;;;;153873:12:0;::::1;;::::0;;153896:14:::1;:12;:14::i;:::-;153784:134:::0;:::o;154096:97::-;122094:5;;-1:-1:-1;;;;;122094:5:0;122080:10;:19;;;;:42;;-1:-1:-1;122117:5:0;;-1:-1:-1;;;;;122117:5:0;122103:10;:19;;122080:42;:69;;;;-1:-1:-1;122138:10:0;122127:22;;;;:10;:22;;;;;;;;122126:23;122080:69;122076:96;;;122158:14;;-1:-1:-1;;;122158:14:0;;;;;;;;;;;122076:96;154152:12:::1;:10;:12::i;:::-;154175:10;:8;:10::i;:::-;154096:97::o:0;121026:110::-;121853:5;;-1:-1:-1;;;;;121853:5:0;121839:10;:19;121835:46;;121867:14;;-1:-1:-1;;;121867:14:0;;;;;;;;;;;121835:46;121102:14:::1;:26:::0;;;::::1;-1:-1:-1::0;;;;;121102:26:0;;;::::1;::::0;;;::::1;::::0;;121026:110::o;148908:72::-;150969:5;;-1:-1:-1;;;;;150969:5:0;150955:10;:19;;;;:42;;-1:-1:-1;150992:5:0;;-1:-1:-1;;;;;150992:5:0;150978:10;:19;;150955:42;:74;;;;-1:-1:-1;151001:10:0;-1:-1:-1;;;;;151023:5:0;151001:28;;;150955:74;150951:101;;;151038:14;;-1:-1:-1;;;151038:14:0;;;;;;;;;;;150951:101;148963:9:::1;:7;:9::i;149361:199::-:0;121853:5;;-1:-1:-1;;;;;121853:5:0;121839:10;:19;121835:46;;121867:14;;-1:-1:-1;;;121867:14:0;;;;;;;;;;;121835:46;149448:8:::1;::::0;-1:-1:-1;;;;;149435:21:0;;::::1;149448:8:::0;::::1;149435:21;149431:48;;;149465:14;;;;;;;;;;;;;;149431:48;149490:8;:20:::0;;;::::1;-1:-1:-1::0;;;;;149490:20:0;::::1;::::0;;::::1;::::0;;;149526:26:::1;::::0;::::1;::::0;-1:-1:-1;;149526:26:0::1;149361:199:::0;:::o;79607:1527::-;79723:12;79898:4;79892:11;80043:66;80024:17;80017:93;80158:2;80154:1;80135:17;80131:25;80124:37;80239:6;80234:2;80215:17;80211:26;80204:42;81051:2;81048:1;81044:2;81025:17;81022:1;81015:5;81008;81003:51;80567:16;80560:24;80554:2;80536:16;80533:24;80529:1;80525;80519:8;80516:15;80512:46;80509:76;80306:763;80295:774;;;81100:7;81092:34;;;;;;;8272:2:1;81092:34:0;;;8254:21:1;8311:2;8291:18;;;8284:30;8350:16;8330:18;;;8323:44;8384:18;;81092:34:0;8070:338:1;155531:585:0;155594:16;155623;155642:26;155660:7;155642:17;:26::i;:::-;155623:45;-1:-1:-1;155764:13:0;155760:34;;155779:15;155531:585;;;:::o;155760:34::-;155853:41;;;;;152108:1;155853:41;;;5413:25:1;5454:18;;;5447:34;;;151451:42:0;;155853:16;;5386:18:1;;155853:41:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;155960:64:0;;;;;152003:2;155960:64;;;8613:38:1;8667:18;;;8660:34;;;156018:4:0;8710:18:1;;;8703:83;151351:42:0;;-1:-1:-1;155960:25:0;;-1:-1:-1;8586:18:1;;155960:64:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;155949:75;;156050:27;156069:7;156050:18;:27::i;:::-;156039:8;:38;156035:73;;;156086:22;;;;;;;;160:25:1;;;133:18;;156086:22:0;14:177:1;156035:73:0;155612:504;155531:585;;;:::o;156124:391::-;156257:34;;;;;152108:1;156257:34;;;5413:25:1;156289:1:0;5454:18:1;;;5447:34;151451:42:0;;156257:16;;5386:18:1;;156257:34:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;156328:28:0;;;;;156350:4;156328:28;;;865:74:1;156304:21:0;;-1:-1:-1;151537:42:0;;-1:-1:-1;156328:13:0;;838:18:1;;156328:28:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;156304:52;-1:-1:-1;156371:18:0;156367:42;;156398:11;;;;;;;;;;;;;;156367:42;156444:4;;:63;;;;;151537:42;156444:63;;;9358:34:1;-1:-1:-1;;;;;156482:5:0;9428:15:1;;9408:18;;;9401:43;9460:18;;;9453:34;;;156444:4:0;9503:18:1;;;9496:34;156444:4:0;;;;:15;;9269:19:1;;156444:63:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;156162:353;156124:391::o;150545:132::-;150654:3;;150608:7;;150635:34;;:7;;150654:3;;;;;146412:6;150635:18;:34::i;:::-;150628:41;150545:132;-1:-1:-1;;150545:132:0:o;157943:169::-;158010:7;158037:67;152168:42;-1:-1:-1;;;;;158056:19:0;;:21;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;152168:42;-1:-1:-1;;;;;158079:22:0;;:24;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;158037:7;;:67;:18;:67::i;157701:87::-;157771:4;;157747:33;;151537:42;;-1:-1:-1;;;;;157771:4:0;;157747:15;:33::i;157834:101::-;157902:4;;157878:49;;151537:42;;-1:-1:-1;;;;;157902:4:0;157909:17;157878:15;:49::i;157488:167::-;157530:37;151745:42;151351;157565:1;157530:17;:37::i;:::-;157578:40;152168:42;151451;157616:1;157578:19;:40::i;:::-;157631:16;:14;:16::i;157181:299::-;157267:53;151745:42;151351;157302:17;157267;:53::i;:::-;157389:56;152168:42;151451;157427:17;157389:19;:56::i;:::-;157458:14;:12;:14::i;156523:534::-;156594:30;;;;;156618:4;156594:30;;;865:74:1;156571:20:0;;156594:5;-1:-1:-1;;;;;156594:15:0;;;;838:18:1;;156594:30:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;156571:53;-1:-1:-1;156639:17:0;156635:47;;156665:17;;;;;;;;;;;;;;156635:47;156695:28;;;;;;;;160:25:1;;;151869:42:0;;156695:14;;133:18:1;;156695:28:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;151745:42;-1:-1:-1;;;;;156734:13:0;;156755:12;156734:36;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;156783:62:0;;;;;152003:2;156783:62;;;8613:38:1;8667:18;;;8660:34;;;156839:4:0;8710:18:1;;;8703:83;151351:42:0;;-1:-1:-1;156783:19:0;;-1:-1:-1;8586:18:1;;;-1:-1:-1;156783:62:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;156876:32:0;;;;;156902:4;156876:32;;;865:74:1;156858:15:0;;-1:-1:-1;152168:42:0;;-1:-1:-1;156876:17:0;;838:18:1;;156876:32:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;156858:50;;156935:32;156954:12;156935:18;:32::i;:::-;156925:7;:42;156921:76;;;156976:21;;;;;;;;160:25:1;;;133:18;;156976:21:0;14:177:1;156921:76:0;157010:39;;;;;152108:1;157010:39;;;5413:25:1;5454:18;;;5447:34;;;151451:42:0;;157010:15;;5386:18:1;;157010:39:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;156560:497;;156523:534::o;150398:139::-;150512:4;;150466:7;;150493:36;;:7;;150512:4;;;;;146602:6;111083:541;111203:9;111455:1;111442:11;111438:19;111435:1;111432:26;111429:1;111425:34;111418:42;111405:11;111401:60;111391:118;;111492:1;111489;111482:12;111391:118;-1:-1:-1;111583:9:0;;111579:27;;111083:541::o;196:180:1:-;255:6;308:2;296:9;287:7;283:23;279:32;276:52;;;324:1;321;314:12;276:52;-1:-1:-1;347:23:1;;196:180;-1:-1:-1;196:180:1:o;1143:159::-;1210:20;;1270:6;1259:18;;1249:29;;1239:57;;1292:1;1289;1282:12;1239:57;1143:159;;;:::o;1307:184::-;1365:6;1418:2;1406:9;1397:7;1393:23;1389:32;1386:52;;;1434:1;1431;1424:12;1386:52;1457:28;1475:9;1457:28;:::i;:::-;1447:38;1307:184;-1:-1:-1;;;1307:184:1:o;1496:154::-;-1:-1:-1;;;;;1575:5:1;1571:54;1564:5;1561:65;1551:93;;1640:1;1637;1630:12;1655:247;1714:6;1767:2;1755:9;1746:7;1742:23;1738:32;1735:52;;;1783:1;1780;1773:12;1735:52;1822:9;1809:23;1841:31;1866:5;1841:31;:::i;2390:526::-;2493:6;2501;2509;2562:2;2550:9;2541:7;2537:23;2533:32;2530:52;;;2578:1;2575;2568:12;2530:52;2601:28;2619:9;2601:28;:::i;:::-;2591:38;;2676:2;2665:9;2661:18;2648:32;2638:42;;2731:2;2720:9;2716:18;2703:32;2758:18;2750:6;2747:30;2744:50;;;2790:1;2787;2780:12;2744:50;2813:22;;2869:2;2851:16;;;2847:25;2844:45;;;2885:1;2882;2875:12;2844:45;2908:2;2898:12;;;2390:526;;;;;:::o;4516:245::-;4595:6;4603;4656:2;4644:9;4635:7;4631:23;4627:32;4624:52;;;4672:1;4669;4662:12;4624:52;-1:-1:-1;;4695:16:1;;4751:2;4736:18;;;4730:25;4695:16;;4730:25;;-1:-1:-1;4516:245:1:o;4766:184::-;4836:6;4889:2;4877:9;4868:7;4864:23;4860:32;4857:52;;;4905:1;4902;4895:12;4857:52;-1:-1:-1;4928:16:1;;4766:184;-1:-1:-1;4766:184:1:o;4955:279::-;4995:4;5023:1;5020;5017:8;5014:188;;;5058:77;5055:1;5048:88;5159:4;5156:1;5149:15;5187:4;5184:1;5177:15;5014:188;-1:-1:-1;5219:9:1;;4955:279::o;5761:939::-;5863:5;5850:19;5845:3;5838:32;5926:4;5919:5;5915:16;5902:30;5895:4;5890:3;5886:14;5879:54;5820:3;5992:4;5985:5;5981:16;5968:30;6073:66;6065:5;6049:14;6045:26;6041:99;6021:18;6017:124;6007:152;;6155:1;6152;6145:12;6007:152;6183:30;;6236:21;;6280:18;6269:30;;6266:50;;;6312:1;6309;6302:12;6266:50;6359:6;6343:14;6339:27;6332:5;6328:39;6325:59;;;6380:1;6377;6370:12;6325:59;6416:4;6409;6404:3;6400:14;6393:28;6453:6;6446:4;6441:3;6437:14;6430:30;6517:6;6510:4;6501:7;6497:18;6491:3;6486;6482:13;6469:55;6568:1;6562:3;6553:6;6548:3;6544:16;6540:26;6533:37;6690:3;6620:66;6615:2;6607:6;6603:15;6599:88;6594:3;6590:98;6586:108;6579:115;;;;5761:939;;;;:::o;6705:1360::-;7047:4;7076:6;7121:2;7113:6;7109:15;7098:9;7091:34;7144:2;7194;7186:6;7182:15;7177:2;7166:9;7162:18;7155:43;7246:2;7238:6;7234:15;7229:2;7218:9;7214:18;7207:43;-1:-1:-1;;;;;7290:6:1;7286:55;7281:2;7270:9;7266:18;7259:83;7379:6;7373:3;7362:9;7358:19;7351:35;7423:3;7417;7406:9;7402:19;7395:32;7456:6;7450:13;7436:27;;7500:6;7494:3;7483:9;7479:19;7472:35;7525:1;7535:141;7549:6;7546:1;7543:13;7535:141;;;7645:14;;;7641:23;;7635:30;7610:17;;;7629:3;7606:27;7599:67;7564:10;;7535:141;;;7694:6;7691:1;7688:13;7685:92;;;7765:1;7759:3;7750:6;7739:9;7735:22;7731:32;7724:43;7685:92;-1:-1:-1;;7827:2:1;7815:15;7832:66;7811:88;7796:104;;7963:18;;;7919:3;7959:27;;;7953:3;7938:19;;7931:56;8004:55;8047:11;;;8039:6;8004:55;:::i;:::-;7996:63;6705:1360;-1:-1:-1;;;;;;;;;;;6705:1360:1:o
Swarm Source
ipfs://bc727841b2b053a7d6b8a974d8ae96afa0d2e60493a50c2cd966fd54d564cf91
Loading...
Loading
Loading...
Loading
Net Worth in USD
$0.00
Net Worth in ETH
0
Multichain Portfolio | 33 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ 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.