Source Code
Latest 1 from a total of 1 transactions
| Transaction Hash |
|
Block
|
From
|
To
|
|||||
|---|---|---|---|---|---|---|---|---|---|
| Initialize | 3332251 | 649 days ago | IN | 0 FRAX | 0.00000265 |
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Cross-Chain Transactions
Loading...
Loading
Contract Name:
VeFXSYieldDistributor
Compiler Version
v0.8.23+commit.f704f362
Contract Source Code (Solidity)
/**
*Submitted for verification at fraxscan.com on 2024-04-18
*/
// SPDX-License-Identifier: GPL-2.0-or-later
pragma solidity >=0.8.0;
// lib/frax-standard-solidity/lib/forge-std/src/console2.sol
/// @dev The original console.sol uses `int` and `uint` for computing function selectors, but it should
/// use `int256` and `uint256`. This modified version fixes that. This version is recommended
/// over `console.sol` if you don't need compatibility with Hardhat as the logs will show up in
/// forge stack traces. If you do need compatibility with Hardhat, you must use `console.sol`.
/// Reference: https://github.com/NomicFoundation/hardhat/issues/2178
library console2 {
address constant CONSOLE_ADDRESS = address(0x000000000000000000636F6e736F6c652e6c6f67);
function _castLogPayloadViewToPure(
function(bytes memory) internal view fnIn
) internal pure returns (function(bytes memory) internal pure fnOut) {
assembly {
fnOut := fnIn
}
}
function _sendLogPayload(bytes memory payload) internal pure {
_castLogPayloadViewToPure(_sendLogPayloadView)(payload);
}
function _sendLogPayloadView(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 pure {
_sendLogPayload(abi.encodeWithSignature("log()"));
}
function logInt(int256 p0) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(int256)", p0));
}
function logUint(uint256 p0) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256)", p0));
}
function logString(string memory p0) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string)", p0));
}
function logBool(bool p0) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool)", p0));
}
function logAddress(address p0) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address)", p0));
}
function logBytes(bytes memory p0) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bytes)", p0));
}
function logBytes1(bytes1 p0) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bytes1)", p0));
}
function logBytes2(bytes2 p0) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bytes2)", p0));
}
function logBytes3(bytes3 p0) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bytes3)", p0));
}
function logBytes4(bytes4 p0) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bytes4)", p0));
}
function logBytes5(bytes5 p0) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bytes5)", p0));
}
function logBytes6(bytes6 p0) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bytes6)", p0));
}
function logBytes7(bytes7 p0) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bytes7)", p0));
}
function logBytes8(bytes8 p0) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bytes8)", p0));
}
function logBytes9(bytes9 p0) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bytes9)", p0));
}
function logBytes10(bytes10 p0) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bytes10)", p0));
}
function logBytes11(bytes11 p0) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bytes11)", p0));
}
function logBytes12(bytes12 p0) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bytes12)", p0));
}
function logBytes13(bytes13 p0) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bytes13)", p0));
}
function logBytes14(bytes14 p0) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bytes14)", p0));
}
function logBytes15(bytes15 p0) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bytes15)", p0));
}
function logBytes16(bytes16 p0) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bytes16)", p0));
}
function logBytes17(bytes17 p0) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bytes17)", p0));
}
function logBytes18(bytes18 p0) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bytes18)", p0));
}
function logBytes19(bytes19 p0) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bytes19)", p0));
}
function logBytes20(bytes20 p0) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bytes20)", p0));
}
function logBytes21(bytes21 p0) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bytes21)", p0));
}
function logBytes22(bytes22 p0) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bytes22)", p0));
}
function logBytes23(bytes23 p0) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bytes23)", p0));
}
function logBytes24(bytes24 p0) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bytes24)", p0));
}
function logBytes25(bytes25 p0) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bytes25)", p0));
}
function logBytes26(bytes26 p0) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bytes26)", p0));
}
function logBytes27(bytes27 p0) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bytes27)", p0));
}
function logBytes28(bytes28 p0) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bytes28)", p0));
}
function logBytes29(bytes29 p0) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bytes29)", p0));
}
function logBytes30(bytes30 p0) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bytes30)", p0));
}
function logBytes31(bytes31 p0) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bytes31)", p0));
}
function logBytes32(bytes32 p0) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bytes32)", p0));
}
function log(uint256 p0) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256)", p0));
}
function log(int256 p0) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(int256)", p0));
}
function log(string memory p0) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string)", p0));
}
function log(bool p0) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool)", p0));
}
function log(address p0) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address)", p0));
}
function log(uint256 p0, uint256 p1) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,uint256)", p0, p1));
}
function log(uint256 p0, string memory p1) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,string)", p0, p1));
}
function log(uint256 p0, bool p1) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,bool)", p0, p1));
}
function log(uint256 p0, address p1) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,address)", p0, p1));
}
function log(string memory p0, uint256 p1) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,uint256)", p0, p1));
}
function log(string memory p0, int256 p1) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,int256)", p0, p1));
}
function log(string memory p0, string memory p1) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,string)", p0, p1));
}
function log(string memory p0, bool p1) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,bool)", p0, p1));
}
function log(string memory p0, address p1) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,address)", p0, p1));
}
function log(bool p0, uint256 p1) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,uint256)", p0, p1));
}
function log(bool p0, string memory p1) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,string)", p0, p1));
}
function log(bool p0, bool p1) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,bool)", p0, p1));
}
function log(bool p0, address p1) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,address)", p0, p1));
}
function log(address p0, uint256 p1) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,uint256)", p0, p1));
}
function log(address p0, string memory p1) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,string)", p0, p1));
}
function log(address p0, bool p1) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,bool)", p0, p1));
}
function log(address p0, address p1) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,address)", p0, p1));
}
function log(uint256 p0, uint256 p1, uint256 p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,uint256)", p0, p1, p2));
}
function log(uint256 p0, uint256 p1, string memory p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,string)", p0, p1, p2));
}
function log(uint256 p0, uint256 p1, bool p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,bool)", p0, p1, p2));
}
function log(uint256 p0, uint256 p1, address p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,address)", p0, p1, p2));
}
function log(uint256 p0, string memory p1, uint256 p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,string,uint256)", p0, p1, p2));
}
function log(uint256 p0, string memory p1, string memory p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,string,string)", p0, p1, p2));
}
function log(uint256 p0, string memory p1, bool p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,string,bool)", p0, p1, p2));
}
function log(uint256 p0, string memory p1, address p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,string,address)", p0, p1, p2));
}
function log(uint256 p0, bool p1, uint256 p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,bool,uint256)", p0, p1, p2));
}
function log(uint256 p0, bool p1, string memory p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,bool,string)", p0, p1, p2));
}
function log(uint256 p0, bool p1, bool p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,bool,bool)", p0, p1, p2));
}
function log(uint256 p0, bool p1, address p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,bool,address)", p0, p1, p2));
}
function log(uint256 p0, address p1, uint256 p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,address,uint256)", p0, p1, p2));
}
function log(uint256 p0, address p1, string memory p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,address,string)", p0, p1, p2));
}
function log(uint256 p0, address p1, bool p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,address,bool)", p0, p1, p2));
}
function log(uint256 p0, address p1, address p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,address,address)", p0, p1, p2));
}
function log(string memory p0, uint256 p1, uint256 p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,uint256,uint256)", p0, p1, p2));
}
function log(string memory p0, uint256 p1, string memory p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,uint256,string)", p0, p1, p2));
}
function log(string memory p0, uint256 p1, bool p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,uint256,bool)", p0, p1, p2));
}
function log(string memory p0, uint256 p1, address p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,uint256,address)", p0, p1, p2));
}
function log(string memory p0, string memory p1, uint256 p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,string,uint256)", p0, p1, p2));
}
function log(string memory p0, string memory p1, string memory p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,string,string)", p0, p1, p2));
}
function log(string memory p0, string memory p1, bool p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,string,bool)", p0, p1, p2));
}
function log(string memory p0, string memory p1, address p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,string,address)", p0, p1, p2));
}
function log(string memory p0, bool p1, uint256 p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,bool,uint256)", p0, p1, p2));
}
function log(string memory p0, bool p1, string memory p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,bool,string)", p0, p1, p2));
}
function log(string memory p0, bool p1, bool p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,bool,bool)", p0, p1, p2));
}
function log(string memory p0, bool p1, address p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,bool,address)", p0, p1, p2));
}
function log(string memory p0, address p1, uint256 p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,address,uint256)", p0, p1, p2));
}
function log(string memory p0, address p1, string memory p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,address,string)", p0, p1, p2));
}
function log(string memory p0, address p1, bool p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,address,bool)", p0, p1, p2));
}
function log(string memory p0, address p1, address p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,address,address)", p0, p1, p2));
}
function log(bool p0, uint256 p1, uint256 p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,uint256,uint256)", p0, p1, p2));
}
function log(bool p0, uint256 p1, string memory p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,uint256,string)", p0, p1, p2));
}
function log(bool p0, uint256 p1, bool p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,uint256,bool)", p0, p1, p2));
}
function log(bool p0, uint256 p1, address p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,uint256,address)", p0, p1, p2));
}
function log(bool p0, string memory p1, uint256 p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,string,uint256)", p0, p1, p2));
}
function log(bool p0, string memory p1, string memory p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,string,string)", p0, p1, p2));
}
function log(bool p0, string memory p1, bool p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,string,bool)", p0, p1, p2));
}
function log(bool p0, string memory p1, address p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,string,address)", p0, p1, p2));
}
function log(bool p0, bool p1, uint256 p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint256)", p0, p1, p2));
}
function log(bool p0, bool p1, string memory p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,bool,string)", p0, p1, p2));
}
function log(bool p0, bool p1, bool p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool)", p0, p1, p2));
}
function log(bool p0, bool p1, address p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,bool,address)", p0, p1, p2));
}
function log(bool p0, address p1, uint256 p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,address,uint256)", p0, p1, p2));
}
function log(bool p0, address p1, string memory p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,address,string)", p0, p1, p2));
}
function log(bool p0, address p1, bool p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,address,bool)", p0, p1, p2));
}
function log(bool p0, address p1, address p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,address,address)", p0, p1, p2));
}
function log(address p0, uint256 p1, uint256 p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,uint256,uint256)", p0, p1, p2));
}
function log(address p0, uint256 p1, string memory p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,uint256,string)", p0, p1, p2));
}
function log(address p0, uint256 p1, bool p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,uint256,bool)", p0, p1, p2));
}
function log(address p0, uint256 p1, address p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,uint256,address)", p0, p1, p2));
}
function log(address p0, string memory p1, uint256 p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,string,uint256)", p0, p1, p2));
}
function log(address p0, string memory p1, string memory p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,string,string)", p0, p1, p2));
}
function log(address p0, string memory p1, bool p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,string,bool)", p0, p1, p2));
}
function log(address p0, string memory p1, address p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,string,address)", p0, p1, p2));
}
function log(address p0, bool p1, uint256 p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,bool,uint256)", p0, p1, p2));
}
function log(address p0, bool p1, string memory p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,bool,string)", p0, p1, p2));
}
function log(address p0, bool p1, bool p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,bool,bool)", p0, p1, p2));
}
function log(address p0, bool p1, address p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,bool,address)", p0, p1, p2));
}
function log(address p0, address p1, uint256 p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,address,uint256)", p0, p1, p2));
}
function log(address p0, address p1, string memory p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,address,string)", p0, p1, p2));
}
function log(address p0, address p1, bool p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,address,bool)", p0, p1, p2));
}
function log(address p0, address p1, address p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,address,address)", p0, p1, p2));
}
function log(uint256 p0, uint256 p1, uint256 p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,uint256,uint256)", p0, p1, p2, p3));
}
function log(uint256 p0, uint256 p1, uint256 p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,uint256,string)", p0, p1, p2, p3));
}
function log(uint256 p0, uint256 p1, uint256 p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,uint256,bool)", p0, p1, p2, p3));
}
function log(uint256 p0, uint256 p1, uint256 p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,uint256,address)", p0, p1, p2, p3));
}
function log(uint256 p0, uint256 p1, string memory p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,string,uint256)", p0, p1, p2, p3));
}
function log(uint256 p0, uint256 p1, string memory p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,string,string)", p0, p1, p2, p3));
}
function log(uint256 p0, uint256 p1, string memory p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,string,bool)", p0, p1, p2, p3));
}
function log(uint256 p0, uint256 p1, string memory p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,string,address)", p0, p1, p2, p3));
}
function log(uint256 p0, uint256 p1, bool p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,bool,uint256)", p0, p1, p2, p3));
}
function log(uint256 p0, uint256 p1, bool p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,bool,string)", p0, p1, p2, p3));
}
function log(uint256 p0, uint256 p1, bool p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,bool,bool)", p0, p1, p2, p3));
}
function log(uint256 p0, uint256 p1, bool p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,bool,address)", p0, p1, p2, p3));
}
function log(uint256 p0, uint256 p1, address p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,address,uint256)", p0, p1, p2, p3));
}
function log(uint256 p0, uint256 p1, address p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,address,string)", p0, p1, p2, p3));
}
function log(uint256 p0, uint256 p1, address p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,address,bool)", p0, p1, p2, p3));
}
function log(uint256 p0, uint256 p1, address p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,address,address)", p0, p1, p2, p3));
}
function log(uint256 p0, string memory p1, uint256 p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,string,uint256,uint256)", p0, p1, p2, p3));
}
function log(uint256 p0, string memory p1, uint256 p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,string,uint256,string)", p0, p1, p2, p3));
}
function log(uint256 p0, string memory p1, uint256 p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,string,uint256,bool)", p0, p1, p2, p3));
}
function log(uint256 p0, string memory p1, uint256 p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,string,uint256,address)", p0, p1, p2, p3));
}
function log(uint256 p0, string memory p1, string memory p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,string,string,uint256)", p0, p1, p2, p3));
}
function log(uint256 p0, string memory p1, string memory p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,string,string,string)", p0, p1, p2, p3));
}
function log(uint256 p0, string memory p1, string memory p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,string,string,bool)", p0, p1, p2, p3));
}
function log(uint256 p0, string memory p1, string memory p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,string,string,address)", p0, p1, p2, p3));
}
function log(uint256 p0, string memory p1, bool p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,string,bool,uint256)", p0, p1, p2, p3));
}
function log(uint256 p0, string memory p1, bool p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,string,bool,string)", p0, p1, p2, p3));
}
function log(uint256 p0, string memory p1, bool p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,string,bool,bool)", p0, p1, p2, p3));
}
function log(uint256 p0, string memory p1, bool p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,string,bool,address)", p0, p1, p2, p3));
}
function log(uint256 p0, string memory p1, address p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,string,address,uint256)", p0, p1, p2, p3));
}
function log(uint256 p0, string memory p1, address p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,string,address,string)", p0, p1, p2, p3));
}
function log(uint256 p0, string memory p1, address p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,string,address,bool)", p0, p1, p2, p3));
}
function log(uint256 p0, string memory p1, address p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,string,address,address)", p0, p1, p2, p3));
}
function log(uint256 p0, bool p1, uint256 p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,bool,uint256,uint256)", p0, p1, p2, p3));
}
function log(uint256 p0, bool p1, uint256 p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,bool,uint256,string)", p0, p1, p2, p3));
}
function log(uint256 p0, bool p1, uint256 p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,bool,uint256,bool)", p0, p1, p2, p3));
}
function log(uint256 p0, bool p1, uint256 p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,bool,uint256,address)", p0, p1, p2, p3));
}
function log(uint256 p0, bool p1, string memory p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,bool,string,uint256)", p0, p1, p2, p3));
}
function log(uint256 p0, bool p1, string memory p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,bool,string,string)", p0, p1, p2, p3));
}
function log(uint256 p0, bool p1, string memory p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,bool,string,bool)", p0, p1, p2, p3));
}
function log(uint256 p0, bool p1, string memory p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,bool,string,address)", p0, p1, p2, p3));
}
function log(uint256 p0, bool p1, bool p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,bool,bool,uint256)", p0, p1, p2, p3));
}
function log(uint256 p0, bool p1, bool p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,bool,bool,string)", p0, p1, p2, p3));
}
function log(uint256 p0, bool p1, bool p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,bool,bool,bool)", p0, p1, p2, p3));
}
function log(uint256 p0, bool p1, bool p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,bool,bool,address)", p0, p1, p2, p3));
}
function log(uint256 p0, bool p1, address p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,bool,address,uint256)", p0, p1, p2, p3));
}
function log(uint256 p0, bool p1, address p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,bool,address,string)", p0, p1, p2, p3));
}
function log(uint256 p0, bool p1, address p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,bool,address,bool)", p0, p1, p2, p3));
}
function log(uint256 p0, bool p1, address p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,bool,address,address)", p0, p1, p2, p3));
}
function log(uint256 p0, address p1, uint256 p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,address,uint256,uint256)", p0, p1, p2, p3));
}
function log(uint256 p0, address p1, uint256 p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,address,uint256,string)", p0, p1, p2, p3));
}
function log(uint256 p0, address p1, uint256 p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,address,uint256,bool)", p0, p1, p2, p3));
}
function log(uint256 p0, address p1, uint256 p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,address,uint256,address)", p0, p1, p2, p3));
}
function log(uint256 p0, address p1, string memory p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,address,string,uint256)", p0, p1, p2, p3));
}
function log(uint256 p0, address p1, string memory p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,address,string,string)", p0, p1, p2, p3));
}
function log(uint256 p0, address p1, string memory p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,address,string,bool)", p0, p1, p2, p3));
}
function log(uint256 p0, address p1, string memory p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,address,string,address)", p0, p1, p2, p3));
}
function log(uint256 p0, address p1, bool p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,address,bool,uint256)", p0, p1, p2, p3));
}
function log(uint256 p0, address p1, bool p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,address,bool,string)", p0, p1, p2, p3));
}
function log(uint256 p0, address p1, bool p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,address,bool,bool)", p0, p1, p2, p3));
}
function log(uint256 p0, address p1, bool p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,address,bool,address)", p0, p1, p2, p3));
}
function log(uint256 p0, address p1, address p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,address,address,uint256)", p0, p1, p2, p3));
}
function log(uint256 p0, address p1, address p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,address,address,string)", p0, p1, p2, p3));
}
function log(uint256 p0, address p1, address p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,address,address,bool)", p0, p1, p2, p3));
}
function log(uint256 p0, address p1, address p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,address,address,address)", p0, p1, p2, p3));
}
function log(string memory p0, uint256 p1, uint256 p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,uint256,uint256,uint256)", p0, p1, p2, p3));
}
function log(string memory p0, uint256 p1, uint256 p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,uint256,uint256,string)", p0, p1, p2, p3));
}
function log(string memory p0, uint256 p1, uint256 p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,uint256,uint256,bool)", p0, p1, p2, p3));
}
function log(string memory p0, uint256 p1, uint256 p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,uint256,uint256,address)", p0, p1, p2, p3));
}
function log(string memory p0, uint256 p1, string memory p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,uint256,string,uint256)", p0, p1, p2, p3));
}
function log(string memory p0, uint256 p1, string memory p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,uint256,string,string)", p0, p1, p2, p3));
}
function log(string memory p0, uint256 p1, string memory p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,uint256,string,bool)", p0, p1, p2, p3));
}
function log(string memory p0, uint256 p1, string memory p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,uint256,string,address)", p0, p1, p2, p3));
}
function log(string memory p0, uint256 p1, bool p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,uint256,bool,uint256)", p0, p1, p2, p3));
}
function log(string memory p0, uint256 p1, bool p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,uint256,bool,string)", p0, p1, p2, p3));
}
function log(string memory p0, uint256 p1, bool p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,uint256,bool,bool)", p0, p1, p2, p3));
}
function log(string memory p0, uint256 p1, bool p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,uint256,bool,address)", p0, p1, p2, p3));
}
function log(string memory p0, uint256 p1, address p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,uint256,address,uint256)", p0, p1, p2, p3));
}
function log(string memory p0, uint256 p1, address p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,uint256,address,string)", p0, p1, p2, p3));
}
function log(string memory p0, uint256 p1, address p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,uint256,address,bool)", p0, p1, p2, p3));
}
function log(string memory p0, uint256 p1, address p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,uint256,address,address)", p0, p1, p2, p3));
}
function log(string memory p0, string memory p1, uint256 p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,string,uint256,uint256)", p0, p1, p2, p3));
}
function log(string memory p0, string memory p1, uint256 p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,string,uint256,string)", p0, p1, p2, p3));
}
function log(string memory p0, string memory p1, uint256 p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,string,uint256,bool)", p0, p1, p2, p3));
}
function log(string memory p0, string memory p1, uint256 p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,string,uint256,address)", p0, p1, p2, p3));
}
function log(string memory p0, string memory p1, string memory p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,string,string,uint256)", p0, p1, p2, p3));
}
function log(string memory p0, string memory p1, string memory p2, string memory p3) internal pure {
_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 pure {
_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 pure {
_sendLogPayload(abi.encodeWithSignature("log(string,string,string,address)", p0, p1, p2, p3));
}
function log(string memory p0, string memory p1, bool p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,string,bool,uint256)", p0, p1, p2, p3));
}
function log(string memory p0, string memory p1, bool p2, string memory p3) internal pure {
_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 pure {
_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 pure {
_sendLogPayload(abi.encodeWithSignature("log(string,string,bool,address)", p0, p1, p2, p3));
}
function log(string memory p0, string memory p1, address p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,string,address,uint256)", p0, p1, p2, p3));
}
function log(string memory p0, string memory p1, address p2, string memory p3) internal pure {
_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 pure {
_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 pure {
_sendLogPayload(abi.encodeWithSignature("log(string,string,address,address)", p0, p1, p2, p3));
}
function log(string memory p0, bool p1, uint256 p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,bool,uint256,uint256)", p0, p1, p2, p3));
}
function log(string memory p0, bool p1, uint256 p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,bool,uint256,string)", p0, p1, p2, p3));
}
function log(string memory p0, bool p1, uint256 p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,bool,uint256,bool)", p0, p1, p2, p3));
}
function log(string memory p0, bool p1, uint256 p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,bool,uint256,address)", p0, p1, p2, p3));
}
function log(string memory p0, bool p1, string memory p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,bool,string,uint256)", p0, p1, p2, p3));
}
function log(string memory p0, bool p1, string memory p2, string memory p3) internal pure {
_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 pure {
_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 pure {
_sendLogPayload(abi.encodeWithSignature("log(string,bool,string,address)", p0, p1, p2, p3));
}
function log(string memory p0, bool p1, bool p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,bool,bool,uint256)", p0, p1, p2, p3));
}
function log(string memory p0, bool p1, bool p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,bool,bool,string)", p0, p1, p2, p3));
}
function log(string memory p0, bool p1, bool p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,bool,bool,bool)", p0, p1, p2, p3));
}
function log(string memory p0, bool p1, bool p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,bool,bool,address)", p0, p1, p2, p3));
}
function log(string memory p0, bool p1, address p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,bool,address,uint256)", p0, p1, p2, p3));
}
function log(string memory p0, bool p1, address p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,bool,address,string)", p0, p1, p2, p3));
}
function log(string memory p0, bool p1, address p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,bool,address,bool)", p0, p1, p2, p3));
}
function log(string memory p0, bool p1, address p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,bool,address,address)", p0, p1, p2, p3));
}
function log(string memory p0, address p1, uint256 p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,address,uint256,uint256)", p0, p1, p2, p3));
}
function log(string memory p0, address p1, uint256 p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,address,uint256,string)", p0, p1, p2, p3));
}
function log(string memory p0, address p1, uint256 p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,address,uint256,bool)", p0, p1, p2, p3));
}
function log(string memory p0, address p1, uint256 p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,address,uint256,address)", p0, p1, p2, p3));
}
function log(string memory p0, address p1, string memory p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,address,string,uint256)", p0, p1, p2, p3));
}
function log(string memory p0, address p1, string memory p2, string memory p3) internal pure {
_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 pure {
_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 pure {
_sendLogPayload(abi.encodeWithSignature("log(string,address,string,address)", p0, p1, p2, p3));
}
function log(string memory p0, address p1, bool p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,address,bool,uint256)", p0, p1, p2, p3));
}
function log(string memory p0, address p1, bool p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,address,bool,string)", p0, p1, p2, p3));
}
function log(string memory p0, address p1, bool p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,address,bool,bool)", p0, p1, p2, p3));
}
function log(string memory p0, address p1, bool p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,address,bool,address)", p0, p1, p2, p3));
}
function log(string memory p0, address p1, address p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,address,address,uint256)", p0, p1, p2, p3));
}
function log(string memory p0, address p1, address p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,address,address,string)", p0, p1, p2, p3));
}
function log(string memory p0, address p1, address p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,address,address,bool)", p0, p1, p2, p3));
}
function log(string memory p0, address p1, address p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,address,address,address)", p0, p1, p2, p3));
}
function log(bool p0, uint256 p1, uint256 p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,uint256,uint256,uint256)", p0, p1, p2, p3));
}
function log(bool p0, uint256 p1, uint256 p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,uint256,uint256,string)", p0, p1, p2, p3));
}
function log(bool p0, uint256 p1, uint256 p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,uint256,uint256,bool)", p0, p1, p2, p3));
}
function log(bool p0, uint256 p1, uint256 p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,uint256,uint256,address)", p0, p1, p2, p3));
}
function log(bool p0, uint256 p1, string memory p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,uint256,string,uint256)", p0, p1, p2, p3));
}
function log(bool p0, uint256 p1, string memory p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,uint256,string,string)", p0, p1, p2, p3));
}
function log(bool p0, uint256 p1, string memory p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,uint256,string,bool)", p0, p1, p2, p3));
}
function log(bool p0, uint256 p1, string memory p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,uint256,string,address)", p0, p1, p2, p3));
}
function log(bool p0, uint256 p1, bool p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,uint256,bool,uint256)", p0, p1, p2, p3));
}
function log(bool p0, uint256 p1, bool p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,uint256,bool,string)", p0, p1, p2, p3));
}
function log(bool p0, uint256 p1, bool p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,uint256,bool,bool)", p0, p1, p2, p3));
}
function log(bool p0, uint256 p1, bool p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,uint256,bool,address)", p0, p1, p2, p3));
}
function log(bool p0, uint256 p1, address p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,uint256,address,uint256)", p0, p1, p2, p3));
}
function log(bool p0, uint256 p1, address p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,uint256,address,string)", p0, p1, p2, p3));
}
function log(bool p0, uint256 p1, address p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,uint256,address,bool)", p0, p1, p2, p3));
}
function log(bool p0, uint256 p1, address p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,uint256,address,address)", p0, p1, p2, p3));
}
function log(bool p0, string memory p1, uint256 p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,string,uint256,uint256)", p0, p1, p2, p3));
}
function log(bool p0, string memory p1, uint256 p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,string,uint256,string)", p0, p1, p2, p3));
}
function log(bool p0, string memory p1, uint256 p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,string,uint256,bool)", p0, p1, p2, p3));
}
function log(bool p0, string memory p1, uint256 p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,string,uint256,address)", p0, p1, p2, p3));
}
function log(bool p0, string memory p1, string memory p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,string,string,uint256)", p0, p1, p2, p3));
}
function log(bool p0, string memory p1, string memory p2, string memory p3) internal pure {
_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 pure {
_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 pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,string,string,address)", p0, p1, p2, p3));
}
function log(bool p0, string memory p1, bool p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,string,bool,uint256)", p0, p1, p2, p3));
}
function log(bool p0, string memory p1, bool p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,string,bool,string)", p0, p1, p2, p3));
}
function log(bool p0, string memory p1, bool p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,string,bool,bool)", p0, p1, p2, p3));
}
function log(bool p0, string memory p1, bool p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,string,bool,address)", p0, p1, p2, p3));
}
function log(bool p0, string memory p1, address p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,string,address,uint256)", p0, p1, p2, p3));
}
function log(bool p0, string memory p1, address p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,string,address,string)", p0, p1, p2, p3));
}
function log(bool p0, string memory p1, address p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,string,address,bool)", p0, p1, p2, p3));
}
function log(bool p0, string memory p1, address p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,string,address,address)", p0, p1, p2, p3));
}
function log(bool p0, bool p1, uint256 p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint256,uint256)", p0, p1, p2, p3));
}
function log(bool p0, bool p1, uint256 p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint256,string)", p0, p1, p2, p3));
}
function log(bool p0, bool p1, uint256 p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint256,bool)", p0, p1, p2, p3));
}
function log(bool p0, bool p1, uint256 p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint256,address)", p0, p1, p2, p3));
}
function log(bool p0, bool p1, string memory p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,bool,string,uint256)", p0, p1, p2, p3));
}
function log(bool p0, bool p1, string memory p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,bool,string,string)", p0, p1, p2, p3));
}
function log(bool p0, bool p1, string memory p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,bool,string,bool)", p0, p1, p2, p3));
}
function log(bool p0, bool p1, string memory p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,bool,string,address)", p0, p1, p2, p3));
}
function log(bool p0, bool p1, bool p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool,uint256)", p0, p1, p2, p3));
}
function log(bool p0, bool p1, bool p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool,string)", p0, p1, p2, p3));
}
function log(bool p0, bool p1, bool p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool,bool)", p0, p1, p2, p3));
}
function log(bool p0, bool p1, bool p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool,address)", p0, p1, p2, p3));
}
function log(bool p0, bool p1, address p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,bool,address,uint256)", p0, p1, p2, p3));
}
function log(bool p0, bool p1, address p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,bool,address,string)", p0, p1, p2, p3));
}
function log(bool p0, bool p1, address p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,bool,address,bool)", p0, p1, p2, p3));
}
function log(bool p0, bool p1, address p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,bool,address,address)", p0, p1, p2, p3));
}
function log(bool p0, address p1, uint256 p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,address,uint256,uint256)", p0, p1, p2, p3));
}
function log(bool p0, address p1, uint256 p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,address,uint256,string)", p0, p1, p2, p3));
}
function log(bool p0, address p1, uint256 p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,address,uint256,bool)", p0, p1, p2, p3));
}
function log(bool p0, address p1, uint256 p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,address,uint256,address)", p0, p1, p2, p3));
}
function log(bool p0, address p1, string memory p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,address,string,uint256)", p0, p1, p2, p3));
}
function log(bool p0, address p1, string memory p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,address,string,string)", p0, p1, p2, p3));
}
function log(bool p0, address p1, string memory p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,address,string,bool)", p0, p1, p2, p3));
}
function log(bool p0, address p1, string memory p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,address,string,address)", p0, p1, p2, p3));
}
function log(bool p0, address p1, bool p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,address,bool,uint256)", p0, p1, p2, p3));
}
function log(bool p0, address p1, bool p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,address,bool,string)", p0, p1, p2, p3));
}
function log(bool p0, address p1, bool p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,address,bool,bool)", p0, p1, p2, p3));
}
function log(bool p0, address p1, bool p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,address,bool,address)", p0, p1, p2, p3));
}
function log(bool p0, address p1, address p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,address,address,uint256)", p0, p1, p2, p3));
}
function log(bool p0, address p1, address p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,address,address,string)", p0, p1, p2, p3));
}
function log(bool p0, address p1, address p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,address,address,bool)", p0, p1, p2, p3));
}
function log(bool p0, address p1, address p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,address,address,address)", p0, p1, p2, p3));
}
function log(address p0, uint256 p1, uint256 p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,uint256,uint256,uint256)", p0, p1, p2, p3));
}
function log(address p0, uint256 p1, uint256 p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,uint256,uint256,string)", p0, p1, p2, p3));
}
function log(address p0, uint256 p1, uint256 p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,uint256,uint256,bool)", p0, p1, p2, p3));
}
function log(address p0, uint256 p1, uint256 p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,uint256,uint256,address)", p0, p1, p2, p3));
}
function log(address p0, uint256 p1, string memory p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,uint256,string,uint256)", p0, p1, p2, p3));
}
function log(address p0, uint256 p1, string memory p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,uint256,string,string)", p0, p1, p2, p3));
}
function log(address p0, uint256 p1, string memory p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,uint256,string,bool)", p0, p1, p2, p3));
}
function log(address p0, uint256 p1, string memory p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,uint256,string,address)", p0, p1, p2, p3));
}
function log(address p0, uint256 p1, bool p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,uint256,bool,uint256)", p0, p1, p2, p3));
}
function log(address p0, uint256 p1, bool p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,uint256,bool,string)", p0, p1, p2, p3));
}
function log(address p0, uint256 p1, bool p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,uint256,bool,bool)", p0, p1, p2, p3));
}
function log(address p0, uint256 p1, bool p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,uint256,bool,address)", p0, p1, p2, p3));
}
function log(address p0, uint256 p1, address p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,uint256,address,uint256)", p0, p1, p2, p3));
}
function log(address p0, uint256 p1, address p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,uint256,address,string)", p0, p1, p2, p3));
}
function log(address p0, uint256 p1, address p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,uint256,address,bool)", p0, p1, p2, p3));
}
function log(address p0, uint256 p1, address p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,uint256,address,address)", p0, p1, p2, p3));
}
function log(address p0, string memory p1, uint256 p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,string,uint256,uint256)", p0, p1, p2, p3));
}
function log(address p0, string memory p1, uint256 p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,string,uint256,string)", p0, p1, p2, p3));
}
function log(address p0, string memory p1, uint256 p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,string,uint256,bool)", p0, p1, p2, p3));
}
function log(address p0, string memory p1, uint256 p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,string,uint256,address)", p0, p1, p2, p3));
}
function log(address p0, string memory p1, string memory p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,string,string,uint256)", p0, p1, p2, p3));
}
function log(address p0, string memory p1, string memory p2, string memory p3) internal pure {
_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 pure {
_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 pure {
_sendLogPayload(abi.encodeWithSignature("log(address,string,string,address)", p0, p1, p2, p3));
}
function log(address p0, string memory p1, bool p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,string,bool,uint256)", p0, p1, p2, p3));
}
function log(address p0, string memory p1, bool p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,string,bool,string)", p0, p1, p2, p3));
}
function log(address p0, string memory p1, bool p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,string,bool,bool)", p0, p1, p2, p3));
}
function log(address p0, string memory p1, bool p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,string,bool,address)", p0, p1, p2, p3));
}
function log(address p0, string memory p1, address p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,string,address,uint256)", p0, p1, p2, p3));
}
function log(address p0, string memory p1, address p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,string,address,string)", p0, p1, p2, p3));
}
function log(address p0, string memory p1, address p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,string,address,bool)", p0, p1, p2, p3));
}
function log(address p0, string memory p1, address p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,string,address,address)", p0, p1, p2, p3));
}
function log(address p0, bool p1, uint256 p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,bool,uint256,uint256)", p0, p1, p2, p3));
}
function log(address p0, bool p1, uint256 p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,bool,uint256,string)", p0, p1, p2, p3));
}
function log(address p0, bool p1, uint256 p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,bool,uint256,bool)", p0, p1, p2, p3));
}
function log(address p0, bool p1, uint256 p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,bool,uint256,address)", p0, p1, p2, p3));
}
function log(address p0, bool p1, string memory p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,bool,string,uint256)", p0, p1, p2, p3));
}
function log(address p0, bool p1, string memory p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,bool,string,string)", p0, p1, p2, p3));
}
function log(address p0, bool p1, string memory p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,bool,string,bool)", p0, p1, p2, p3));
}
function log(address p0, bool p1, string memory p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,bool,string,address)", p0, p1, p2, p3));
}
function log(address p0, bool p1, bool p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,bool,bool,uint256)", p0, p1, p2, p3));
}
function log(address p0, bool p1, bool p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,bool,bool,string)", p0, p1, p2, p3));
}
function log(address p0, bool p1, bool p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,bool,bool,bool)", p0, p1, p2, p3));
}
function log(address p0, bool p1, bool p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,bool,bool,address)", p0, p1, p2, p3));
}
function log(address p0, bool p1, address p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,bool,address,uint256)", p0, p1, p2, p3));
}
function log(address p0, bool p1, address p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,bool,address,string)", p0, p1, p2, p3));
}
function log(address p0, bool p1, address p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,bool,address,bool)", p0, p1, p2, p3));
}
function log(address p0, bool p1, address p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,bool,address,address)", p0, p1, p2, p3));
}
function log(address p0, address p1, uint256 p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,address,uint256,uint256)", p0, p1, p2, p3));
}
function log(address p0, address p1, uint256 p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,address,uint256,string)", p0, p1, p2, p3));
}
function log(address p0, address p1, uint256 p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,address,uint256,bool)", p0, p1, p2, p3));
}
function log(address p0, address p1, uint256 p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,address,uint256,address)", p0, p1, p2, p3));
}
function log(address p0, address p1, string memory p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,address,string,uint256)", p0, p1, p2, p3));
}
function log(address p0, address p1, string memory p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,address,string,string)", p0, p1, p2, p3));
}
function log(address p0, address p1, string memory p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,address,string,bool)", p0, p1, p2, p3));
}
function log(address p0, address p1, string memory p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,address,string,address)", p0, p1, p2, p3));
}
function log(address p0, address p1, bool p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,address,bool,uint256)", p0, p1, p2, p3));
}
function log(address p0, address p1, bool p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,address,bool,string)", p0, p1, p2, p3));
}
function log(address p0, address p1, bool p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,address,bool,bool)", p0, p1, p2, p3));
}
function log(address p0, address p1, bool p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,address,bool,address)", p0, p1, p2, p3));
}
function log(address p0, address p1, address p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,address,address,uint256)", p0, p1, p2, p3));
}
function log(address p0, address p1, address p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,address,address,string)", p0, p1, p2, p3));
}
function log(address p0, address p1, address p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,address,address,bool)", p0, p1, p2, p3));
}
function log(address p0, address p1, address p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,address,address,address)", p0, p1, p2, p3));
}
}
// node_modules/@openzeppelin/contracts/security/ReentrancyGuard.sol
// OpenZeppelin Contracts v4.4.1 (security/ReentrancyGuard.sol)
/**
* @dev Contract module that helps prevent reentrant calls to a function.
*
* Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier
* available, which can be applied to functions to make sure there are no nested
* (reentrant) calls to them.
*
* Note that because there is a single `nonReentrant` guard, functions marked as
* `nonReentrant` may not call one another. This can be worked around by making
* those functions `private`, and then adding `external` `nonReentrant` entry
* points to them.
*
* TIP: If you would like to learn more about reentrancy and alternative ways
* to protect against it, check out our blog post
* https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].
*/
abstract contract ReentrancyGuard {
// Booleans are more expensive than uint256 or any type that takes up a full
// word because each write operation emits an extra SLOAD to first read the
// slot's contents, replace the bits taken up by the boolean, and then write
// back. This is the compiler's defense against contract upgrades and
// pointer aliasing, and it cannot be disabled.
// The values being non-zero value makes deployment a bit more expensive,
// but in exchange the refund on every call to nonReentrant will be lower in
// amount. Since refunds are capped to a percentage of the total
// transaction's gas, it is best to keep them low in cases like this one, to
// increase the likelihood of the full refund coming into effect.
uint256 private constant _NOT_ENTERED = 1;
uint256 private constant _ENTERED = 2;
uint256 private _status;
constructor() {
_status = _NOT_ENTERED;
}
/**
* @dev Prevents a contract from calling itself, directly or indirectly.
* Calling a `nonReentrant` function from another `nonReentrant`
* function is not supported. It is possible to prevent this from happening
* by making the `nonReentrant` function external, and making it call a
* `private` function that does the actual work.
*/
modifier nonReentrant() {
// On the first call to nonReentrant, _notEntered will be true
require(_status != _ENTERED, "ReentrancyGuard: reentrant call");
// Any calls to nonReentrant after this point will fail
_status = _ENTERED;
_;
// By storing the original value once again, a refund is triggered (see
// https://eips.ethereum.org/EIPS/eip-2200)
_status = _NOT_ENTERED;
}
}
// node_modules/@openzeppelin/contracts/token/ERC20/IERC20.sol
// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)
/**
* @dev Interface of the ERC20 standard as defined in the EIP.
*/
interface IERC20 {
/**
* @dev Emitted when `value` tokens are moved from one account (`from`) to
* another (`to`).
*
* Note that `value` may be zero.
*/
event Transfer(address indexed from, address indexed to, uint256 value);
/**
* @dev Emitted when the allowance of a `spender` for an `owner` is set by
* a call to {approve}. `value` is the new allowance.
*/
event Approval(address indexed owner, address indexed spender, uint256 value);
/**
* @dev Returns the amount of tokens in existence.
*/
function totalSupply() external view returns (uint256);
/**
* @dev Returns the amount of tokens owned by `account`.
*/
function balanceOf(address account) external view returns (uint256);
/**
* @dev Moves `amount` tokens from the caller's account to `to`.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transfer(address to, uint256 amount) external returns (bool);
/**
* @dev Returns the remaining number of tokens that `spender` will be
* allowed to spend on behalf of `owner` through {transferFrom}. This is
* zero by default.
*
* This value changes when {approve} or {transferFrom} are called.
*/
function allowance(address owner, address spender) external view returns (uint256);
/**
* @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* IMPORTANT: Beware that changing an allowance with this method brings the risk
* that someone may use both the old and the new allowance by unfortunate
* transaction ordering. One possible solution to mitigate this race
* condition is to first reduce the spender's allowance to 0 and set the
* desired value afterwards:
* https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
*
* Emits an {Approval} event.
*/
function approve(address spender, uint256 amount) external returns (bool);
/**
* @dev Moves `amount` tokens from `from` to `to` using the
* allowance mechanism. `amount` is then deducted from the caller's
* allowance.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transferFrom(
address from,
address to,
uint256 amount
) external returns (bool);
}
// node_modules/@openzeppelin/contracts/token/ERC20/extensions/draft-IERC20Permit.sol
// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-IERC20Permit.sol)
/**
* @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in
* https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].
*
* Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by
* presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't
* need to send a transaction, and thus is not required to hold Ether at all.
*/
interface IERC20Permit {
/**
* @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,
* given ``owner``'s signed approval.
*
* IMPORTANT: The same issues {IERC20-approve} has related to transaction
* ordering also apply here.
*
* Emits an {Approval} event.
*
* Requirements:
*
* - `spender` cannot be the zero address.
* - `deadline` must be a timestamp in the future.
* - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`
* over the EIP712-formatted function arguments.
* - the signature must use ``owner``'s current nonce (see {nonces}).
*
* For more information on the signature format, see the
* https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP
* section].
*/
function permit(
address owner,
address spender,
uint256 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) external;
/**
* @dev Returns the current nonce for `owner`. This value must be
* included whenever a signature is generated for {permit}.
*
* Every successful call to {permit} increases ``owner``'s nonce by one. This
* prevents a signature from being used multiple times.
*/
function nonces(address owner) external view returns (uint256);
/**
* @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.
*/
// solhint-disable-next-line func-name-mixedcase
function DOMAIN_SEPARATOR() external view returns (bytes32);
}
// node_modules/@openzeppelin/contracts/utils/Address.sol
// OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol)
/**
* @dev Collection of functions related to the address type
*/
library Address {
/**
* @dev Returns true if `account` is a contract.
*
* [IMPORTANT]
* ====
* It is unsafe to assume that an address for which this function returns
* false is an externally-owned account (EOA) and not a contract.
*
* Among others, `isContract` will return false for the following
* types of addresses:
*
* - an externally-owned account
* - a contract in construction
* - an address where a contract will be created
* - an address where a contract lived, but was destroyed
* ====
*
* [IMPORTANT]
* ====
* You shouldn't rely on `isContract` to protect against flash loan attacks!
*
* Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets
* like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract
* constructor.
* ====
*/
function isContract(address account) internal view returns (bool) {
// This method relies on extcodesize/address.code.length, which returns 0
// for contracts in construction, since the code is only stored at the end
// of the constructor execution.
return account.code.length > 0;
}
/**
* @dev Replacement for Solidity's `transfer`: sends `amount` wei to
* `recipient`, forwarding all available gas and reverting on errors.
*
* https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
* of certain opcodes, possibly making contracts go over the 2300 gas limit
* imposed by `transfer`, making them unable to receive funds via
* `transfer`. {sendValue} removes this limitation.
*
* https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].
*
* IMPORTANT: because control is transferred to `recipient`, care must be
* taken to not create reentrancy vulnerabilities. Consider using
* {ReentrancyGuard} or the
* https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
*/
function sendValue(address payable recipient, uint256 amount) internal {
require(address(this).balance >= amount, "Address: insufficient balance");
(bool success, ) = recipient.call{value: amount}("");
require(success, "Address: unable to send value, recipient may have reverted");
}
/**
* @dev Performs a Solidity function call using a low level `call`. A
* plain `call` is an unsafe replacement for a function call: use this
* function instead.
*
* If `target` reverts with a revert reason, it is bubbled up by this
* function (like regular Solidity function calls).
*
* Returns the raw returned data. To convert to the expected return value,
* use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
*
* Requirements:
*
* - `target` must be a contract.
* - calling `target` with `data` must not revert.
*
* _Available since v3.1._
*/
function functionCall(address target, bytes memory data) internal returns (bytes memory) {
return functionCall(target, data, "Address: low-level call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with
* `errorMessage` as a fallback revert reason when `target` reverts.
*
* _Available since v3.1._
*/
function functionCall(
address target,
bytes memory data,
string memory errorMessage
) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but also transferring `value` wei to `target`.
*
* Requirements:
*
* - the calling contract must have an ETH balance of at least `value`.
* - the called Solidity function must be `payable`.
*
* _Available since v3.1._
*/
function functionCallWithValue(
address target,
bytes memory data,
uint256 value
) internal returns (bytes memory) {
return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
}
/**
* @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but
* with `errorMessage` as a fallback revert reason when `target` reverts.
*
* _Available since v3.1._
*/
function functionCallWithValue(
address target,
bytes memory data,
uint256 value,
string memory errorMessage
) internal returns (bytes memory) {
require(address(this).balance >= value, "Address: insufficient balance for call");
require(isContract(target), "Address: call to non-contract");
(bool success, bytes memory returndata) = target.call{value: value}(data);
return verifyCallResult(success, returndata, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but performing a static call.
*
* _Available since v3.3._
*/
function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
return functionStaticCall(target, data, "Address: low-level static call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
* but performing a static call.
*
* _Available since v3.3._
*/
function functionStaticCall(
address target,
bytes memory data,
string memory errorMessage
) internal view returns (bytes memory) {
require(isContract(target), "Address: static call to non-contract");
(bool success, bytes memory returndata) = target.staticcall(data);
return verifyCallResult(success, returndata, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but performing a delegate call.
*
* _Available since v3.4._
*/
function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
return functionDelegateCall(target, data, "Address: low-level delegate call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
* but performing a delegate call.
*
* _Available since v3.4._
*/
function functionDelegateCall(
address target,
bytes memory data,
string memory errorMessage
) internal returns (bytes memory) {
require(isContract(target), "Address: delegate call to non-contract");
(bool success, bytes memory returndata) = target.delegatecall(data);
return verifyCallResult(success, returndata, errorMessage);
}
/**
* @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the
* revert reason using the provided one.
*
* _Available since v4.3._
*/
function verifyCallResult(
bool success,
bytes memory returndata,
string memory errorMessage
) internal pure returns (bytes memory) {
if (success) {
return returndata;
} else {
// Look for revert reason and bubble it up if present
if (returndata.length > 0) {
// The easiest way to bubble the revert reason is using memory via assembly
/// @solidity memory-safe-assembly
assembly {
let returndata_size := mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert(errorMessage);
}
}
}
}
// node_modules/@openzeppelin/contracts/utils/Context.sol
// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)
/**
* @dev Provides information about the current execution context, including the
* sender of the transaction and its data. While these are generally available
* via msg.sender and msg.data, they should not be accessed in such a direct
* manner, since when dealing with meta-transactions the account sending and
* paying for execution may not be the actual sender (as far as an application
* is concerned).
*
* This contract is only required for intermediate, library-like contracts.
*/
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
}
// src/contracts/VestedFXS-and-Flox/FPISLocker/IlFPISStructs.sol
// @version 0.2.8
/**
* ====================================================================
* | ______ _______ |
* | / _____________ __ __ / ____(_____ ____ _____ ________ |
* | / /_ / ___/ __ `| |/_/ / /_ / / __ \/ __ `/ __ \/ ___/ _ \ |
* | / __/ / / / /_/ _> < / __/ / / / / / /_/ / / / / /__/ __/ |
* | /_/ /_/ \__,_/_/|_| /_/ /_/_/ /_/\__,_/_/ /_/\___/\___/ |
* | |
* ====================================================================
* ======================== lFPISStructs ==============================
* ====================================================================
* Structs of lFPIS contracts (lFPIS)
* Frax Finance: https://github.com/FraxFinance
*/
interface IlFPISStructs {
/// @notice Detailed lock info for a user
/// @param user Address of the user
/// @param allLocks All of the locks of the user
/// @param numberOfLocks The total number of locks that the user has
/// @param activeLocks Only the active locks of the user
/// @param expiredLocks Only the expired locks of the user
/// @param totalFpis The total amount of FPIS that the user has for all, active, and expired locks respectively
struct DetailedUserLockInfo {
address user;
uint256 numberOfLocks;
LockedBalanceExtended[] allLocks;
LockedBalanceExtended[] activeLocks;
LockedBalanceExtended[] expiredLocks;
int128[3] totalFpis;
}
/// @notice Basic information about a lock
/// @param amount The amount that is locked
/// @param end The ending timestamp for the lock
/// @dev We cannot really do block numbers per se b/c slope is per time, not per block and per block could be fairly bad b/c Ethereum changes blocktimes. What we can do is to extrapolate ***At functions
struct LockedBalance {
int128 amount;
uint128 end; // This should more than suffice for our needs and allows the struct to be packed
}
/// @notice Extended information about a lock
/// @param id The ID of the lock
/// @param index The index of the lock. If index is 0, do not trust it unless isInUse is also true
/// @param amount The amount that is locked
/// @param end The ending timestamp for the lock
/// @param isInUse If the lock ID is currently in use
struct LockedBalanceExtended {
uint256 id;
uint128 index;
int128 amount;
uint128 end;
}
/// @notice Lock ID Info. Cannot be a simple mapping because lock indeces are in constant flux and index 0 vs null is ambiguous.
/// @param id The ID of the lock
/// @param index The index of the lock. If index is 0, do not trust it unless isInUse is also true
/// @param isInUse If the lock ID is currently in use
struct LockIdIdxInfo {
uint256 id;
uint128 index;
bool isInUse;
}
/// @notice Point in a user's lock
/// @param bias The bias of the point
/// @param slope The slope of the point
/// @param ts The timestamp of the point
/// @param blk The block of the point
/// @param fpisAmt The amount of FPIS at the point
struct Point {
int128 bias;
int128 slope; // - dweight / dt
uint256 ts;
uint256 blk; // block
uint256 fpisAmt;
}
/// @notice Longest lock info for a user
/// @param lock The longest lock of the user
/// @param lockIndex The index of the longest lock
/// @param user The address of the user
struct LongestLock {
LockedBalance lock;
uint128 lockIndex;
address user;
}
}
// src/contracts/VestedFXS-and-Flox/Flox/TransferHelper.sol
// helper methods for interacting with ERC20 tokens and sending ETH that do not consistently return true/false
library TransferHelper {
error TransferHelperApproveFailed();
error TransferHelperTransferFailed();
error TransferHelperTransferFromFailed();
error TransferHelperTransferETHFailed();
function safeApprove(address token, address to, uint256 value) internal {
// bytes4(keccak256(bytes('approve(address,uint256)')));
(bool success, bytes memory data) = token.call(abi.encodeWithSelector(0x095ea7b3, to, value));
// require(success && (data.length == 0 || abi.decode(data, (bool))), 'TransferHelper: APPROVE_FAILED');
if (!success || (data.length != 0 && !abi.decode(data, (bool)))) revert TransferHelperApproveFailed();
}
function safeTransfer(address token, address to, uint256 value) internal {
// bytes4(keccak256(bytes('transfer(address,uint256)')));
(bool success, bytes memory data) = token.call(abi.encodeWithSelector(0xa9059cbb, to, value));
// require(success && (data.length == 0 || abi.decode(data, (bool))), 'TransferHelper: TRANSFER_FAILED');
if (!success || (data.length != 0 && !abi.decode(data, (bool)))) revert TransferHelperTransferFailed();
}
function safeTransferFrom(address token, address from, address to, uint256 value) internal {
// bytes4(keccak256(bytes('transferFrom(address,address,uint256)')));
(bool success, bytes memory data) = token.call(abi.encodeWithSelector(0x23b872dd, from, to, value));
// require(success && (data.length == 0 || abi.decode(data, (bool))), 'TransferHelper: TRANSFER_FROM_FAILED');
if (!success || (data.length != 0 && !abi.decode(data, (bool)))) revert TransferHelperTransferFromFailed();
}
function safeTransferETH(address to, uint256 value) internal {
(bool success, ) = to.call{ value: value }(new bytes(0));
// require(success, 'TransferHelper: ETH_TRANSFER_FAILED');
if (!success) revert TransferHelperTransferETHFailed();
}
}
// src/contracts/VestedFXS-and-Flox/VestedFXS/IveFXSStructs.sol
// @version 0.2.8
/**
* ====================================================================
* | ______ _______ |
* | / _____________ __ __ / ____(_____ ____ _____ ________ |
* | / /_ / ___/ __ `| |/_/ / /_ / / __ \/ __ `/ __ \/ ___/ _ \ |
* | / __/ / / / /_/ _> < / __/ / / / / / /_/ / / / / /__/ __/ |
* | /_/ /_/ \__,_/_/|_| /_/ /_/_/ /_/\__,_/_/ /_/\___/\___/ |
* | |
* ====================================================================
* =============================== veFXS ==============================
* ====================================================================
* Structs VestedFXS (veFXS)
* Frax Finance: https://github.com/FraxFinance
*/
interface IveFXSStructs {
/// @notice Detailed lock info for a user
/// @param user Address of the user
/// @param allLocks All of the locks of the user
/// @param numberOfLocks The total number of locks that the user has
/// @param activeLocks Only the active locks of the user
/// @param expiredLocks Only the expired locks of the user
/// @param totalFxs The total amount of FXS that the user has for all, active, and expired locks respectively
struct DetailedUserLockInfo {
address user;
uint256 numberOfLocks;
LockedBalanceExtended[] allLocks;
LockedBalanceExtended[] activeLocks;
LockedBalanceExtended[] expiredLocks;
int128[3] totalFxs;
}
/// @notice Basic information about a lock
/// @param amount The amount that is locked
/// @param end The ending timestamp for the lock
/// @dev We cannot really do block numbers per se b/c slope is per time, not per block and per block could be fairly bad b/c Ethereum changes blocktimes. What we can do is to extrapolate ***At functions
struct LockedBalance {
int128 amount;
uint128 end; // This should more than suffice for our needs and allows the struct to be packed
}
/// @notice Extended information about a lock
/// @param id The ID of the lock
/// @param index The index of the lock. If index is 0, do not trust it unless isInUse is also true
/// @param amount The amount that is locked
/// @param end The ending timestamp for the lock
/// @param isInUse If the lock ID is currently in use
struct LockedBalanceExtended {
uint256 id;
uint128 index;
int128 amount;
uint128 end;
}
/// @notice Lock ID Info. Cannot be a simple mapping because lock indeces are in constant flux and index 0 vs null is ambiguous.
/// @param id The ID of the lock
/// @param index The index of the lock. If index is 0, do not trust it unless isInUse is also true
/// @param isInUse If the lock ID is currently in use
struct LockIdIdxInfo {
uint256 id;
uint128 index;
bool isInUse;
}
/// @notice Point in a user's lock
/// @param bias The bias of the point
/// @param slope The slope of the point
/// @param ts The timestamp of the point
/// @param blk The block of the point
/// @param fxsAmt The amount of FXS at the point
struct Point {
int128 bias;
int128 slope; // - dweight / dt
uint256 ts;
uint256 blk; // block
uint256 fxsAmt;
}
/// @notice Longest lock info for a user
/// @param lock The longest lock of the user
/// @param lockIndex The index of the longest lock
/// @param user The address of the user
struct LongestLock {
LockedBalance lock;
uint128 lockIndex;
address user;
}
}
// src/contracts/VestedFXS-and-Flox/VestedFXS/OwnedV2.sol
// https://docs.synthetix.io/contracts/Owned
contract OwnedV2 {
error OwnerCannotBeZero();
error InvalidOwnershipAcceptance();
error OnlyOwner();
address public owner;
address public nominatedOwner;
constructor(address _owner) {
// require(_owner != address(0), "Owner address cannot be 0");
if (_owner == address(0)) revert OwnerCannotBeZero();
owner = _owner;
emit OwnerChanged(address(0), _owner);
}
function nominateNewOwner(address _owner) external onlyOwner {
nominatedOwner = _owner;
emit OwnerNominated(_owner);
}
function acceptOwnership() external {
// require(msg.sender == nominatedOwner, "You must be nominated before you can accept ownership");
if (msg.sender != nominatedOwner) revert InvalidOwnershipAcceptance();
emit OwnerChanged(owner, nominatedOwner);
owner = nominatedOwner;
nominatedOwner = address(0);
}
modifier onlyOwner() {
// require(msg.sender == owner, "Only the contract owner may perform this action");
if (msg.sender != owner) revert OnlyOwner();
_;
}
function _onlyOwner() internal view {
if (msg.sender != owner) revert OnlyOwner();
}
event OwnerNominated(address newOwner);
event OwnerChanged(address oldOwner, address newOwner);
}
// src/contracts/VestedFXS-and-Flox/VestedFXS/OwnedV2AutoMsgSender.sol
// https://docs.synthetix.io/contracts/Owned
contract OwnedV2AutoMsgSender {
error OwnerCannotBeZero();
error InvalidOwnershipAcceptance();
error OnlyOwner();
address public owner;
address public nominatedOwner;
constructor() {
owner = msg.sender;
emit OwnerChanged(address(0), msg.sender);
}
function nominateNewOwner(address _owner) external onlyOwner {
nominatedOwner = _owner;
emit OwnerNominated(_owner);
}
function acceptOwnership() external {
// require(msg.sender == nominatedOwner, "You must be nominated before you can accept ownership");
if (msg.sender != nominatedOwner) revert InvalidOwnershipAcceptance();
emit OwnerChanged(owner, nominatedOwner);
owner = nominatedOwner;
nominatedOwner = address(0);
}
modifier onlyOwner() {
// require(msg.sender == owner, "Only the contract owner may perform this action");
if (msg.sender != owner) revert OnlyOwner();
_;
}
function _onlyOwner() internal view {
if (msg.sender != owner) revert OnlyOwner();
}
event OwnerNominated(address newOwner);
event OwnerChanged(address oldOwner, address newOwner);
}
// src/contracts/VestedFXS-and-Flox/interfaces/IL1VeFXS.sol
// @version 0.2.8
interface IL1VeFXS {
/// @dev amount and end of lock
struct LockedBalance {
uint128 amount;
uint64 end;
uint64 blockTimestamp;
}
function LOCKED_SLOT_INDEX() external view returns (uint256);
function acceptOwnership() external;
function adminProofVeFXS(address[] memory _addresses, LockedBalance[] memory _lockedBalances) external;
function balanceOf(address _address) external view returns (uint256 _balance);
function initialize(address _stateRootOracle, address _owner) external;
function locked(address account) external view returns (LockedBalance memory);
function owner() external view returns (address);
function pendingOwner() external view returns (address);
function proofVeFXS(
address _address,
uint256 _blockNumber,
bytes[] memory _accountProof,
bytes[] memory _storageProof1,
bytes[] memory _storageProof2
) external;
function renounceOwnership() external;
function transferOwnership(address newOwner) external;
function veFXSAddress() external view returns (address);
}
// node_modules/@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol
// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)
/**
* @dev Interface for the optional metadata functions from the ERC20 standard.
*
* _Available since v4.1._
*/
interface IERC20Metadata is IERC20 {
/**
* @dev Returns the name of the token.
*/
function name() external view returns (string memory);
/**
* @dev Returns the symbol of the token.
*/
function symbol() external view returns (string memory);
/**
* @dev Returns the decimals places of the token.
*/
function decimals() external view returns (uint8);
}
// src/contracts/VestedFXS-and-Flox/VestedFXS/L1VeFXSTotalSupplyOracle.sol
/**
* ====================================================================
* | ______ _______ |
* | / _____________ __ __ / ____(_____ ____ _____ ________ |
* | / /_ / ___/ __ `| |/_/ / /_ / / __ \/ __ `/ __ \/ ___/ _ \ |
* | / __/ / / / /_/ _> < / __/ / / / / / /_/ / / / / /__/ __/ |
* | /_/ /_/ \__,_/_/|_| /_/ /_/_/ /_/\__,_/_/ /_/\___/\___/ |
* | |
* ====================================================================
* ===================== L1VeFXSTotalSupplyOracle =====================
* ====================================================================
* Bot-set Oracle for reporting the Ethereum Mainnet veFXS totalSupply() info.
* Eventually plan to update L1VeFXS with a proof-based solution
* Frax Finance: https://github.com/FraxFinance
*/
/* solhint-disable max-line-length, not-rely-on-time */
contract L1VeFXSTotalSupplyOracle is OwnedV2 {
/// @notice The last veFXS totalSupply data point
uint256 private totalSupplyStored;
/// @notice The timestamp on Mainnet when the veFXS totalSupply was read
uint128 private tsWhenTotalSupplyRead;
/// @notice When the information was last updated by the bot
uint256 public lastBotUpdate;
/// @notice Address of the bot that is allowed to update the contract
address public botAddress;
/**
* @notice Initialize contract
* @param _owner The owner of this contract
* @param _bot Address of the bot that is allowed to post
* @param _initTtlSupplyStored Initial/seed value of totalSupplyStored
* @param _initTsWhenTtlSupplyRead Initial/seed value of tsWhenTotalSupplyRead
*/
constructor(
address _owner,
address _bot,
uint256 _initTtlSupplyStored,
uint128 _initTsWhenTtlSupplyRead
) OwnedV2(_owner) {
// Set bot address
botAddress = _bot;
// Set seed values
totalSupplyStored = _initTtlSupplyStored;
tsWhenTotalSupplyRead = _initTsWhenTtlSupplyRead;
if (_initTsWhenTtlSupplyRead > 0) lastBotUpdate = _initTsWhenTtlSupplyRead;
}
/* ========== MODIFIERS ========== */
modifier onlyByOwnBot() {
require(msg.sender == owner || msg.sender == botAddress, "You are not the owner or the bot");
_;
}
/* ============ VIEWS ============ */
/// @notice Get the most recent totalSupply from Mainnet veFXS
/// @param _totalSupply The last reported Mainnet veFXS totalSupply
function totalSupply() external view returns (uint256 _totalSupply) {
return totalSupplyStored;
}
/// @notice Get the most recent totalSupply from Mainnet veFXS along with the time it was read
/// @param _totalSupply The last reported Mainnet veFXS totalSupply
/// @param _ts Timestamp when the totalSupply was read on Mainnet
function totalSupplyExtra() external view returns (uint256 _totalSupply, uint128 _ts) {
return (totalSupplyStored, tsWhenTotalSupplyRead);
}
// ==============================================================================
// BOT FUNCTIONS
// ==============================================================================
/// @notice Set the most recent totalSupply from Mainnet veFXS
/// @param _totalSupply The last reported Mainnet veFXS totalSupply
function updateInfo(uint256 _totalSupply, uint128 _ts) external onlyByOwnBot {
totalSupplyStored = _totalSupply;
tsWhenTotalSupplyRead = _ts;
}
// ==============================================================================
// RESTRICTED FUNCTIONS
// ==============================================================================
/// @notice Set the bot address
/// @param _newBot The address of the timelock
function setTimelock(address _newBot) external onlyOwner {
botAddress = _newBot;
}
// ==============================================================================
// EVENTS
// ==============================================================================
/// @notice When the veFXS info is updated
/// @param totalSupply veFXS totalSupply from mainnet
/// @param ts Timestamp when the totalSupply was read on Mainnet
event InfoUpdated(uint256 totalSupply, uint128 ts);
}
// src/contracts/VestedFXS-and-Flox/interfaces/IFPISLocker.sol
// @version 0.2.8
/**
* ====================================================================
* | ______ _______ |
* | / _____________ __ __ / ____(_____ ____ _____ ________ |
* | / /_ / ___/ __ `| |/_/ / /_ / / __ \/ __ `/ __ \/ ___/ _ \ |
* | / __/ / / / /_/ _> < / __/ / / / / / /_/ / / / / /__/ __/ |
* | /_/ /_/ \__,_/_/|_| /_/ /_/_/ /_/\__,_/_/ /_/\___/\___/ |
* | |
* ====================================================================
* ============================ IFPISLocker ============================
* ====================================================================
* Frax Finance: https://github.com/FraxFinance
*/
interface IFPISLocker is IlFPISStructs {
function MAXTIME_INT128() external view returns (int128);
function MAXTIME_UINT256() external view returns (uint256);
function MAX_CONTRIBUTOR_LOCKS() external view returns (uint8);
function MAX_USER_LOCKS() external view returns (uint8);
function MULTIPLIER_UINT256() external view returns (uint256);
function VOTE_WEIGHT_MULTIPLIER_INT128() external view returns (int128);
function VOTE_WEIGHT_MULTIPLIER_UINT256() external view returns (uint256);
function VOTE_END_POWER_BASIS_POINTS_INT128() external view returns (int128);
function VOTE_END_POWER_BASIS_POINTS_UINT256() external view returns (uint256);
function MAX_BASIS_POINTS_INT128() external view returns (int128);
function MAX_BASIS_POINTS_UINT256() external view returns (uint256);
function WEEK_UINT128() external view returns (uint128);
function WEEK_UINT256() external view returns (uint256);
function acceptTransferOwnership() external;
function admin() external view returns (address);
function balanceOf(address _addr) external view returns (uint256 _balance);
function balanceOfAllLocksAtBlock(address _addr, uint256 _block) external view returns (uint256 _balance);
function balanceOfAllLocksAtTime(address _addr, uint256 _timestamp) external view returns (uint256 _balance);
function balanceOfAt(address _addr, uint256 _block) external view returns (uint256 _balance);
function balanceOfOneLockAtBlock(
address _addr,
uint128 _lockIndex,
uint256 _block
) external view returns (uint256 _balance);
function balanceOfOneLockAtTime(
address _addr,
uint128 _lockIndex,
uint256 _timestamp
) external view returns (uint256 _balance);
function checkpoint() external;
function commitTransferOwnership(address _addr) external;
function createLock(address _addr, uint256 _value, uint128 _unlockTime) external returns (uint128);
function decimals() external view returns (uint256);
function depositFor(address _addr, uint256 _value, uint128 _lockIndex) external;
function emergencyUnlockActive() external view returns (bool);
function epoch() external view returns (uint256);
function findBlockEpoch(uint256 _block, uint256 _maxEpoch) external view returns (uint256);
function floxContributors(address) external view returns (bool);
function futureAdmin() external view returns (address);
function getLastUserSlope(address _addr, uint128 _lockIndex) external view returns (int128);
function increaseAmount(uint256 _value, uint128 _lockIndex) external;
function increaseUnlockTime(uint128 _unlockTime, uint128 _lockIndex) external;
function indicesToIds(address, uint128) external view returns (uint256);
function isPaused() external view returns (bool);
function locked(address, uint256) external view returns (int128 amount, uint128 end);
function lockedById(address _addr, uint256 _id) external view returns (LockedBalance memory _lockInfo);
function lockedByIndex(address _addr, uint128 _index) external view returns (LockedBalance memory _lockInfo);
function lockedEnd(address _addr, uint128 _index) external view returns (uint256);
function name() external view returns (string memory);
function nextId(address) external view returns (uint256);
function numLocks(address) external view returns (uint128);
function pointHistory(
uint256
) external view returns (int128 bias, int128 slope, uint256 ts, uint256 blk, uint256 fpisAmt);
function recoverIERC20(address _tokenAddr, uint256 _amount) external;
function setFloxContributor(address _floxContributor, bool _isFloxContributor) external;
function setLVPIDUtils(address _lFpisUtilsAddr) external;
function slopeChanges(uint256) external view returns (int128);
function supply() external view returns (uint256);
function supplyAt(Point memory _point, uint256 _t) external view returns (uint256);
function symbol() external view returns (string memory);
function toggleContractPause() external;
function activateEmergencyUnlock() external;
function token() external view returns (address);
function totalFPISSupply() external view returns (uint256);
function totalFPISSupplyAt(uint256 _block) external view returns (uint256);
function totalSupply() external view returns (uint256);
function totalSupply(uint256 _timestamp) external view returns (uint256);
function totalSupplyAt(uint256 _block) external view returns (uint256);
function userPointEpoch(address, uint256) external view returns (uint256);
function userPointHistory(
address,
uint256,
uint256
) external view returns (int128 bias, int128 slope, uint256 ts, uint256 blk, uint256 fpisAmt);
function userPointHistoryTs(address _addr, uint128 _lockIndex, uint256 _idx) external view returns (uint256);
function lFpisUtils() external view returns (address);
function version() external view returns (string memory);
function withdraw(uint128 _lockIndex) external;
}
// src/contracts/VestedFXS-and-Flox/interfaces/IVestedFXS.sol
// @version 0.2.8
/**
* ====================================================================
* | ______ _______ |
* | / _____________ __ __ / ____(_____ ____ _____ ________ |
* | / /_ / ___/ __ `| |/_/ / /_ / / __ \/ __ `/ __ \/ ___/ _ \ |
* | / __/ / / / /_/ _> < / __/ / / / / / /_/ / / / / /__/ __/ |
* | /_/ /_/ \__,_/_/|_| /_/ /_/_/ /_/\__,_/_/ /_/\___/\___/ |
* | |
* ====================================================================
* ============================ IVestedFXS ============================
* ====================================================================
* Frax Finance: https://github.com/FraxFinance
*/
interface IVestedFXS is IveFXSStructs {
function MAXTIME_INT128() external view returns (int128);
function MAXTIME_UINT256() external view returns (uint256);
function MAX_CONTRIBUTOR_LOCKS() external view returns (uint8);
function MAX_USER_LOCKS() external view returns (uint8);
function MULTIPLIER_UINT256() external view returns (uint256);
function VOTE_WEIGHT_MULTIPLIER_INT128() external view returns (int128);
function VOTE_WEIGHT_MULTIPLIER_UINT256() external view returns (uint256);
function WEEK_UINT128() external view returns (uint128);
function WEEK_UINT256() external view returns (uint256);
function acceptTransferOwnership() external;
function admin() external view returns (address);
function balanceOf(address _addr) external view returns (uint256 _balance);
function balanceOfAllLocksAtBlock(address _addr, uint256 _block) external view returns (uint256 _balance);
function balanceOfAllLocksAtTime(address _addr, uint256 _timestamp) external view returns (uint256 _balance);
function balanceOfAt(address _addr, uint256 _block) external view returns (uint256 _balance);
function balanceOfOneLockAtBlock(
address _addr,
uint128 _lockIndex,
uint256 _block
) external view returns (uint256 _balance);
function balanceOfOneLockAtTime(
address _addr,
uint128 _lockIndex,
uint256 _timestamp
) external view returns (uint256 _balance);
function checkpoint() external;
function commitTransferOwnership(address _addr) external;
function createLock(address _addr, uint256 _value, uint128 _unlockTime) external returns (uint128);
function decimals() external view returns (uint256);
function depositFor(address _addr, uint256 _value, uint128 _lockIndex) external;
function emergencyUnlockActive() external view returns (bool);
function epoch() external view returns (uint256);
function findBlockEpoch(uint256 _block, uint256 _maxEpoch) external view returns (uint256);
function floxContributors(address) external view returns (bool);
function futureAdmin() external view returns (address);
function getLastUserSlope(address _addr, uint128 _lockIndex) external view returns (int128);
function increaseAmount(uint256 _value, uint128 _lockIndex) external;
function increaseUnlockTime(uint128 _unlockTime, uint128 _lockIndex) external;
function indicesToIds(address, uint128) external view returns (uint256);
function isPaused() external view returns (bool);
function locked(address, uint256) external view returns (int128 amount, uint128 end);
function lockedById(address _addr, uint256 _id) external view returns (LockedBalance memory _lockInfo);
function lockedByIndex(address _addr, uint128 _index) external view returns (LockedBalance memory _lockInfo);
function lockedEnd(address _addr, uint128 _index) external view returns (uint256);
function name() external view returns (string memory);
function nextId(address) external view returns (uint256);
function numLocks(address) external view returns (uint128);
function pointHistory(
uint256
) external view returns (int128 bias, int128 slope, uint256 ts, uint256 blk, uint256 fxsAmt);
function recoverIERC20(address _tokenAddr, uint256 _amount) external;
function setFloxContributor(address _floxContributor, bool _isFloxContributor) external;
function setVeFXSUtils(address _veFxsUtilsAddr) external;
function slopeChanges(uint256) external view returns (int128);
function supply() external view returns (uint256);
function supplyAt(Point memory _point, uint256 _t) external view returns (uint256);
function symbol() external view returns (string memory);
function toggleContractPause() external;
function activateEmergencyUnlock() external;
function token() external view returns (address);
function totalFXSSupply() external view returns (uint256);
function totalFXSSupplyAt(uint256 _block) external view returns (uint256);
function totalSupply() external view returns (uint256);
function totalSupply(uint256 _timestamp) external view returns (uint256);
function totalSupplyAt(uint256 _block) external view returns (uint256);
function userPointEpoch(address, uint256) external view returns (uint256);
function userPointHistory(
address,
uint256,
uint256
) external view returns (int128 bias, int128 slope, uint256 ts, uint256 blk, uint256 fxsAmt);
function userPointHistoryTs(address _addr, uint128 _lockIndex, uint256 _idx) external view returns (uint256);
function veFxsUtils() external view returns (address);
function version() external view returns (string memory);
function withdraw(uint128 _lockIndex) external;
function numberOfFloxContributorCreatedLocks(address _user) external view returns (uint256);
}
// src/contracts/VestedFXS-and-Flox/interfaces/IVestedFXSUtils.sol
// @version 0.2.8
/**
* ====================================================================
* | ______ _______ |
* | / _____________ __ __ / ____(_____ ____ _____ ________ |
* | / /_ / ___/ __ `| |/_/ / /_ / / __ \/ __ `/ __ \/ ___/ _ \ |
* | / __/ / / / /_/ _> < / __/ / / / / / /_/ / / / / /__/ __/ |
* | /_/ /_/ \__,_/_/|_| /_/ /_/_/ /_/\__,_/_/ /_/\___/\___/ |
* | |
* ====================================================================
* ========================= IVestedFXSUtils ==========================
* ====================================================================
* Interface for helper and utility functions for VestedFXS
* Frax Finance: https://github.com/FraxFinance
*/
interface IVestedFXSUtils is IveFXSStructs {
function getDetailedUserLockInfo(address user) external view returns (DetailedUserLockInfo memory);
function getDetailedUserLockInfoBulk(address[] memory users) external view returns (DetailedUserLockInfo[] memory);
function getLongestLock(address user) external view returns (LockedBalance memory, uint128);
function getLongestLockBulk(address[] memory users) external view returns (LongestLock[] memory);
function getCrudeExpectedVeFXSOneLock(int128 _fxsAmount, uint128 _lockSecsU128) external view returns (uint256);
function getCrudeExpectedVeFXSMultiLock(
int128[] memory _fxsAmounts,
uint128[] memory _lockSecsU128
) external view returns (uint256);
function getCrudeExpectedVeFXSUser(address _user) external view returns (uint256);
}
// node_modules/@openzeppelin/contracts/token/ERC20/ERC20.sol
// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/ERC20.sol)
/**
* @dev Implementation of the {IERC20} interface.
*
* This implementation is agnostic to the way tokens are created. This means
* that a supply mechanism has to be added in a derived contract using {_mint}.
* For a generic mechanism see {ERC20PresetMinterPauser}.
*
* TIP: For a detailed writeup see our guide
* https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How
* to implement supply mechanisms].
*
* We have followed general OpenZeppelin Contracts guidelines: functions revert
* instead returning `false` on failure. This behavior is nonetheless
* conventional and does not conflict with the expectations of ERC20
* applications.
*
* Additionally, an {Approval} event is emitted on calls to {transferFrom}.
* This allows applications to reconstruct the allowance for all accounts just
* by listening to said events. Other implementations of the EIP may not emit
* these events, as it isn't required by the specification.
*
* Finally, the non-standard {decreaseAllowance} and {increaseAllowance}
* functions have been added to mitigate the well-known issues around setting
* allowances. See {IERC20-approve}.
*/
contract ERC20 is Context, IERC20, IERC20Metadata {
mapping(address => uint256) private _balances;
mapping(address => mapping(address => uint256)) private _allowances;
uint256 private _totalSupply;
string private _name;
string private _symbol;
/**
* @dev Sets the values for {name} and {symbol}.
*
* The default value of {decimals} is 18. To select a different value for
* {decimals} you should overload it.
*
* All two of these values are immutable: they can only be set once during
* construction.
*/
constructor(string memory name_, string memory symbol_) {
_name = name_;
_symbol = symbol_;
}
/**
* @dev Returns the name of the token.
*/
function name() public view virtual override returns (string memory) {
return _name;
}
/**
* @dev Returns the symbol of the token, usually a shorter version of the
* name.
*/
function symbol() public view virtual override returns (string memory) {
return _symbol;
}
/**
* @dev Returns the number of decimals used to get its user representation.
* For example, if `decimals` equals `2`, a balance of `505` tokens should
* be displayed to a user as `5.05` (`505 / 10 ** 2`).
*
* Tokens usually opt for a value of 18, imitating the relationship between
* Ether and Wei. This is the value {ERC20} uses, unless this function is
* overridden;
*
* NOTE: This information is only used for _display_ purposes: it in
* no way affects any of the arithmetic of the contract, including
* {IERC20-balanceOf} and {IERC20-transfer}.
*/
function decimals() public view virtual override returns (uint8) {
return 18;
}
/**
* @dev See {IERC20-totalSupply}.
*/
function totalSupply() public view virtual override returns (uint256) {
return _totalSupply;
}
/**
* @dev See {IERC20-balanceOf}.
*/
function balanceOf(address account) public view virtual override returns (uint256) {
return _balances[account];
}
/**
* @dev See {IERC20-transfer}.
*
* Requirements:
*
* - `to` cannot be the zero address.
* - the caller must have a balance of at least `amount`.
*/
function transfer(address to, uint256 amount) public virtual override returns (bool) {
address owner = _msgSender();
_transfer(owner, to, amount);
return true;
}
/**
* @dev See {IERC20-allowance}.
*/
function allowance(address owner, address spender) public view virtual override returns (uint256) {
return _allowances[owner][spender];
}
/**
* @dev See {IERC20-approve}.
*
* NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on
* `transferFrom`. This is semantically equivalent to an infinite approval.
*
* Requirements:
*
* - `spender` cannot be the zero address.
*/
function approve(address spender, uint256 amount) public virtual override returns (bool) {
address owner = _msgSender();
_approve(owner, spender, amount);
return true;
}
/**
* @dev See {IERC20-transferFrom}.
*
* Emits an {Approval} event indicating the updated allowance. This is not
* required by the EIP. See the note at the beginning of {ERC20}.
*
* NOTE: Does not update the allowance if the current allowance
* is the maximum `uint256`.
*
* Requirements:
*
* - `from` and `to` cannot be the zero address.
* - `from` must have a balance of at least `amount`.
* - the caller must have allowance for ``from``'s tokens of at least
* `amount`.
*/
function transferFrom(
address from,
address to,
uint256 amount
) public virtual override returns (bool) {
address spender = _msgSender();
_spendAllowance(from, spender, amount);
_transfer(from, to, amount);
return true;
}
/**
* @dev Atomically increases the allowance granted to `spender` by the caller.
*
* This is an alternative to {approve} that can be used as a mitigation for
* problems described in {IERC20-approve}.
*
* Emits an {Approval} event indicating the updated allowance.
*
* Requirements:
*
* - `spender` cannot be the zero address.
*/
function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {
address owner = _msgSender();
_approve(owner, spender, allowance(owner, spender) + addedValue);
return true;
}
/**
* @dev Atomically decreases the allowance granted to `spender` by the caller.
*
* This is an alternative to {approve} that can be used as a mitigation for
* problems described in {IERC20-approve}.
*
* Emits an {Approval} event indicating the updated allowance.
*
* Requirements:
*
* - `spender` cannot be the zero address.
* - `spender` must have allowance for the caller of at least
* `subtractedValue`.
*/
function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {
address owner = _msgSender();
uint256 currentAllowance = allowance(owner, spender);
require(currentAllowance >= subtractedValue, "ERC20: decreased allowance below zero");
unchecked {
_approve(owner, spender, currentAllowance - subtractedValue);
}
return true;
}
/**
* @dev Moves `amount` of tokens from `from` to `to`.
*
* This internal function is equivalent to {transfer}, and can be used to
* e.g. implement automatic token fees, slashing mechanisms, etc.
*
* Emits a {Transfer} event.
*
* Requirements:
*
* - `from` cannot be the zero address.
* - `to` cannot be the zero address.
* - `from` must have a balance of at least `amount`.
*/
function _transfer(
address from,
address to,
uint256 amount
) internal virtual {
require(from != address(0), "ERC20: transfer from the zero address");
require(to != address(0), "ERC20: transfer to the zero address");
_beforeTokenTransfer(from, to, amount);
uint256 fromBalance = _balances[from];
require(fromBalance >= amount, "ERC20: transfer amount exceeds balance");
unchecked {
_balances[from] = fromBalance - amount;
}
_balances[to] += amount;
emit Transfer(from, to, amount);
_afterTokenTransfer(from, to, amount);
}
/** @dev Creates `amount` tokens and assigns them to `account`, increasing
* the total supply.
*
* Emits a {Transfer} event with `from` set to the zero address.
*
* Requirements:
*
* - `account` cannot be the zero address.
*/
function _mint(address account, uint256 amount) internal virtual {
require(account != address(0), "ERC20: mint to the zero address");
_beforeTokenTransfer(address(0), account, amount);
_totalSupply += amount;
_balances[account] += amount;
emit Transfer(address(0), account, amount);
_afterTokenTransfer(address(0), account, amount);
}
/**
* @dev Destroys `amount` tokens from `account`, reducing the
* total supply.
*
* Emits a {Transfer} event with `to` set to the zero address.
*
* Requirements:
*
* - `account` cannot be the zero address.
* - `account` must have at least `amount` tokens.
*/
function _burn(address account, uint256 amount) internal virtual {
require(account != address(0), "ERC20: burn from the zero address");
_beforeTokenTransfer(account, address(0), amount);
uint256 accountBalance = _balances[account];
require(accountBalance >= amount, "ERC20: burn amount exceeds balance");
unchecked {
_balances[account] = accountBalance - amount;
}
_totalSupply -= amount;
emit Transfer(account, address(0), amount);
_afterTokenTransfer(account, address(0), amount);
}
/**
* @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.
*
* This internal function is equivalent to `approve`, and can be used to
* e.g. set automatic allowances for certain subsystems, etc.
*
* Emits an {Approval} event.
*
* Requirements:
*
* - `owner` cannot be the zero address.
* - `spender` cannot be the zero address.
*/
function _approve(
address owner,
address spender,
uint256 amount
) internal virtual {
require(owner != address(0), "ERC20: approve from the zero address");
require(spender != address(0), "ERC20: approve to the zero address");
_allowances[owner][spender] = amount;
emit Approval(owner, spender, amount);
}
/**
* @dev Updates `owner` s allowance for `spender` based on spent `amount`.
*
* Does not update the allowance amount in case of infinite allowance.
* Revert if not enough allowance is available.
*
* Might emit an {Approval} event.
*/
function _spendAllowance(
address owner,
address spender,
uint256 amount
) internal virtual {
uint256 currentAllowance = allowance(owner, spender);
if (currentAllowance != type(uint256).max) {
require(currentAllowance >= amount, "ERC20: insufficient allowance");
unchecked {
_approve(owner, spender, currentAllowance - amount);
}
}
}
/**
* @dev Hook that is called before any transfer of tokens. This includes
* minting and burning.
*
* Calling conditions:
*
* - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens
* will be transferred to `to`.
* - when `from` is zero, `amount` tokens will be minted for `to`.
* - when `to` is zero, `amount` of ``from``'s tokens will be burned.
* - `from` and `to` are never both zero.
*
* To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
*/
function _beforeTokenTransfer(
address from,
address to,
uint256 amount
) internal virtual {}
/**
* @dev Hook that is called after any transfer of tokens. This includes
* minting and burning.
*
* Calling conditions:
*
* - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens
* has been transferred to `to`.
* - when `from` is zero, `amount` tokens have been minted for `to`.
* - when `to` is zero, `amount` of ``from``'s tokens have been burned.
* - `from` and `to` are never both zero.
*
* To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
*/
function _afterTokenTransfer(
address from,
address to,
uint256 amount
) internal virtual {}
}
// node_modules/@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol
// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/utils/SafeERC20.sol)
/**
* @title SafeERC20
* @dev Wrappers around ERC20 operations that throw on failure (when the token
* contract returns false). Tokens that return no value (and instead revert or
* throw on failure) are also supported, non-reverting calls are assumed to be
* successful.
* To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,
* which allows you to call the safe operations as `token.safeTransfer(...)`, etc.
*/
library SafeERC20 {
using Address for address;
function safeTransfer(
IERC20 token,
address to,
uint256 value
) internal {
_callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));
}
function safeTransferFrom(
IERC20 token,
address from,
address to,
uint256 value
) internal {
_callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));
}
/**
* @dev Deprecated. This function has issues similar to the ones found in
* {IERC20-approve}, and its usage is discouraged.
*
* Whenever possible, use {safeIncreaseAllowance} and
* {safeDecreaseAllowance} instead.
*/
function safeApprove(
IERC20 token,
address spender,
uint256 value
) internal {
// safeApprove should only be called when setting an initial allowance,
// or when resetting it to zero. To increase and decrease it, use
// 'safeIncreaseAllowance' and 'safeDecreaseAllowance'
require(
(value == 0) || (token.allowance(address(this), spender) == 0),
"SafeERC20: approve from non-zero to non-zero allowance"
);
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));
}
function safeIncreaseAllowance(
IERC20 token,
address spender,
uint256 value
) internal {
uint256 newAllowance = token.allowance(address(this), spender) + value;
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
}
function safeDecreaseAllowance(
IERC20 token,
address spender,
uint256 value
) internal {
unchecked {
uint256 oldAllowance = token.allowance(address(this), spender);
require(oldAllowance >= value, "SafeERC20: decreased allowance below zero");
uint256 newAllowance = oldAllowance - value;
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
}
}
function safePermit(
IERC20Permit token,
address owner,
address spender,
uint256 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) internal {
uint256 nonceBefore = token.nonces(owner);
token.permit(owner, spender, value, deadline, v, r, s);
uint256 nonceAfter = token.nonces(owner);
require(nonceAfter == nonceBefore + 1, "SafeERC20: permit did not succeed");
}
/**
* @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
* on the return value: the return value is optional (but if data is returned, it must not be false).
* @param token The token targeted by the call.
* @param data The call data (encoded using abi.encode or one of its variants).
*/
function _callOptionalReturn(IERC20 token, bytes memory data) private {
// We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since
// we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that
// the target address contains contract code and also asserts for success in the low-level call.
bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed");
if (returndata.length > 0) {
// Return data is optional
require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed");
}
}
}
// src/contracts/VestedFXS-and-Flox/FPISLocker/FPISLockerUtils.sol
// @version 0.2.8
/**
* ====================================================================
* | ______ _______ |
* | / _____________ __ __ / ____(_____ ____ _____ ________ |
* | / /_ / ___/ __ `| |/_/ / /_ / / __ \/ __ `/ __ \/ ___/ _ \ |
* | / __/ / / / /_/ _> < / __/ / / / / / /_/ / / / / /__/ __/ |
* | /_/ /_/ \__,_/_/|_| /_/ /_/_/ /_/\__,_/_/ /_/\___/\___/ |
* | |
* ====================================================================
* ========================= FPISLockerUtils ==========================
* ====================================================================
* Helper and utility functions for VestedFXS
* Frax Finance: https://github.com/FraxFinance
*/
/**
*
* Voting escrow to have time-weighted votes
* Votes have a weight depending on time, so that users are committed
* to the future of (whatever they are voting for).
* The weight in this implementation is linear, and lock cannot be more than maxtime:
* w ^
* 1 + /
* | /
* | /
* | /
* |/
* 0 +--------+------> time
* maxtime (4 years?)
*/
/**
* @title FPISLockerUtils
* @author Frax Finance
* @notice This utility smart contract provides functions to get extended information from the FPISLocker contract.
*/
contract FPISLockerUtils is IlFPISStructs {
IFPISLocker public immutable lFPIS;
IERC20Metadata public immutable token;
/**
* @notice Contract constructor
* @param _FPISLocker Address of the FPISLocker contract
*/
constructor(address _FPISLocker) {
lFPIS = IFPISLocker(_FPISLocker);
token = IERC20Metadata(lFPIS.token());
}
/**
* @notice Used to get all of the locks of a given user.
* @dev The locks are retrieved indiscriminately, regardless of whether they are active or expired.
* @param _user Address of the user
* @return _userLockInfo DetailedUserLockInfo for the user. Includes _allLocks, _activeLocks, _expiredLocks, and FXS totals for these respectively
* @dev This lives on Fraxtal and will mostly be read-called in UIs, so gas not really an issue here
*/
function getDetailedUserLockInfo(address _user) public view returns (DetailedUserLockInfo memory _userLockInfo) {
// Get the total number of locks
uint256 _totalLocks = lFPIS.numLocks(_user);
uint128 _numberOfActiveLocks;
// Set the number locks for the user
_userLockInfo.numberOfLocks = _totalLocks;
// Set the user
_userLockInfo.user = _user;
// Initialize _allLocks
_userLockInfo.allLocks = new LockedBalanceExtended[](_totalLocks);
// Initial _isActive, which tracks if a given index is active
bool[] memory _isActive = new bool[](_totalLocks);
// Loop through all of the locks
for (uint256 i; i < _userLockInfo.allLocks.length; ) {
// Update the _allLocks return data
LockedBalance memory _thisLock = lFPIS.lockedByIndex(_user, uint128(i));
_userLockInfo.allLocks[i].id = lFPIS.indicesToIds(_user, uint128(i));
_userLockInfo.allLocks[i].index = uint128(i);
_userLockInfo.allLocks[i].amount = _thisLock.amount;
_userLockInfo.allLocks[i].end = _thisLock.end;
_userLockInfo.totalFpis[0] += _thisLock.amount;
// Determine whether it is active or expired
if (_thisLock.end > block.timestamp) {
// Update isActive tracking
_isActive[i] = true;
// Update _totalFxs for active locks
_userLockInfo.totalFpis[1] += _thisLock.amount;
unchecked {
++_numberOfActiveLocks;
}
} else {
// Update _totalFxs for expired locks
_userLockInfo.totalFpis[2] += _thisLock.amount;
}
unchecked {
++i;
}
}
// Initialize _activeLocks and _expiredLocks
_userLockInfo.activeLocks = new LockedBalanceExtended[](_numberOfActiveLocks);
_userLockInfo.expiredLocks = new LockedBalanceExtended[](_totalLocks - _numberOfActiveLocks);
// Loop through all of the locks again, this time for assigning to _activeLocks and _expiredLocks
uint128 _activeCounter;
uint128 _expiredCounter;
for (uint256 i; i < _userLockInfo.allLocks.length; ) {
// Get the lock info
LockedBalanceExtended memory _thisLock = _userLockInfo.allLocks[i];
// Sort the lock as either active or expired
if (_isActive[i]) {
// Active
_userLockInfo.activeLocks[_activeCounter] = _thisLock;
unchecked {
++_activeCounter;
}
} else {
// Expired
_userLockInfo.expiredLocks[_expiredCounter] = _thisLock;
unchecked {
++_expiredCounter;
}
}
unchecked {
++i;
}
}
}
/**
* @notice Used to get all of the locks of the given users. Same underlying code as getDetailedUserLockInfo
* @dev The locks are retrieved indiscriminately, regardless of whether they are active or expired.
* @param _users Addresses of the users
* @return _userLockInfos DetailedUserLockInfo[] for the users. Includes _allLocks, _activeLocks, _expiredLocks, and FXS totals for these respectively
* @dev This lives on Fraxtal and will mostly be read-called in UIs, so gas not really an issue here
*/
function getDetailedUserLockInfoBulk(
address[] memory _users
) public view returns (DetailedUserLockInfo[] memory _userLockInfos) {
// Save the number of user addresses
uint256 _numUsers = _users.length;
// Initialize the return array
_userLockInfos = new DetailedUserLockInfo[](_numUsers);
// Loop through all of the users and get their detailed lock info
for (uint256 i = 0; i < _numUsers; ) {
_userLockInfos[i] = getDetailedUserLockInfo(_users[i]);
unchecked {
i++;
}
}
}
/**
* @notice Used to get the longest lock of a given user.
* @dev The longest lock is the lock with the timestamp furthest in the future (can also be in the past if there are no active locks).
* @param user Address of the user
* @return The longest lock of the user
* @return The index of the longest lock
*/
function getLongestLock(address user) public view returns (LockedBalance memory, uint128) {
LockedBalance[] memory locks = new LockedBalance[](lFPIS.numLocks(user));
LockedBalance memory longestLock;
uint128 longestLockIndex;
for (uint256 i = 0; i < locks.length; ) {
uint128 currentEnd = lFPIS.lockedByIndex(user, uint128(i)).end;
if (currentEnd > longestLock.end) {
longestLock.end = currentEnd;
longestLock.amount = lFPIS.lockedByIndex(user, uint128(i)).amount;
longestLockIndex = uint128(i);
}
unchecked {
i++;
}
}
return (longestLock, longestLockIndex);
}
/**
* @notice Used to get longest locks of muliple users.
* @dev This returns the longest lock indiscriminately, regardless of whether it is active or expired.
* @dev The return value is an array of LongestLock structs, which contain the lock, the index of the lock, and the user.
* @param users Array of addresses of the users
* @return The LongestLocks of the users
*/
function getLongestLockBulk(address[] memory users) public view returns (LongestLock[] memory) {
LongestLock[] memory longestLocks = new LongestLock[](users.length);
LockedBalance memory longestLock;
uint128 longestLockIndex;
for (uint256 i = 0; i < users.length; ) {
for (uint256 j; j < lFPIS.numLocks(users[i]); ) {
uint128 currentEnd = lFPIS.lockedByIndex(users[i], uint128(j)).end;
if (currentEnd > longestLock.end) {
longestLock.end = currentEnd;
longestLock.amount = lFPIS.lockedByIndex(users[i], uint128(j)).amount;
longestLockIndex = uint128(j);
}
unchecked {
++j;
}
}
longestLocks[i] = LongestLock({ lock: longestLock, lockIndex: longestLockIndex, user: users[i] });
delete longestLock;
delete longestLockIndex;
unchecked {
++i;
}
}
return longestLocks;
}
/**
* @notice Calculate the APPROXIMATE amount of lFPIS, given an FPIS amount and a lock length. Cruder version of balanceOf math. Useful for sanity checks.
* @param _fpisAmount The amount of FPIS
* @param _lockSecsU128 The length of the lock
* @return _expectedLFPIS The expected amount of lFPIS. May be slightly off from actual (~1%)
* @dev Useful to compare to the slope/bias-based balancedOf to make sure the math is working
*/
function getCrudeExpectedLFPISOneLock(
int128 _fpisAmount,
uint128 _lockSecsU128
) public view returns (uint256 _expectedLFPIS) {
// lFPIS = FPIS in emergency unlock situation
if (lFPIS.emergencyUnlockActive()) return uint256(int256(_fpisAmount));
// Truncate _timeLeft down to the nearest week
int128 _lockSecsI128 = int128((_lockSecsU128 / lFPIS.WEEK_UINT128()) * lFPIS.WEEK_UINT128());
// Calculate the expected lFPIS
_expectedLFPIS = uint256(
uint128(
((_fpisAmount * lFPIS.VOTE_END_POWER_BASIS_POINTS_INT128()) / lFPIS.MAX_BASIS_POINTS_INT128()) +
((_fpisAmount * _lockSecsI128) / lFPIS.MAXTIME_INT128())
)
);
}
/**
* @notice Calculate the APPROXIMATE amount of lFPIS, given FPIS amounts and lock lengths. Cruder version of balanceOf math. Useful for sanity checks.
* @param _fpisAmounts The amounts of FPIS
* @param _lockSecsU128 The length of the locks
* @return _expectedLFPIS The expected amount of lFPIS (summed). May be slightly off from actual (~1%)
* @dev Useful to compare to the slope/bias-based balancedOf to make sure the math is working
*/
function getCrudeExpectedLFPISMultiLock(
int128[] memory _fpisAmounts,
uint128[] memory _lockSecsU128
) public view returns (uint256 _expectedLFPIS) {
// See if you are in an emergency unlock situation
bool _isEmergencyUnlockActive = lFPIS.emergencyUnlockActive();
// Loop through the locks
for (uint128 i = 0; i < _fpisAmounts.length; ++i) {
// lFPIS = FPIS in emergency unlock situation
if (_isEmergencyUnlockActive) _expectedLFPIS += uint256(int256(_fpisAmounts[i]));
else _expectedLFPIS += getCrudeExpectedLFPISOneLock(_fpisAmounts[i], _lockSecsU128[i]);
}
}
/**
* @notice Calculate the APPROXIMATE amount of lFPIS a specific user should have. Cruder version of balanceOf math. Useful for sanity checks.
* @param _user The address of the user
* @return _expectedLFPIS The expected amount of lFPIS (summed). May be slightly off from actual (~1%)
* @dev Useful to compare to the slope/bias-based balancedOf to make sure the math is working
*/
function getCrudeExpectedLFPISUser(address _user) public view returns (uint256 _expectedLFPIS) {
// Get all of the user's locks
DetailedUserLockInfo memory _userLockInfo = getDetailedUserLockInfo(_user);
// See if you are in an emergency unlock situation
bool _isEmergencyUnlockActive = lFPIS.emergencyUnlockActive();
// Loop through all of the user's locks
for (uint128 i = 0; i < _userLockInfo.numberOfLocks; ) {
// Get the lock info
LockedBalanceExtended memory _lockInfo = _userLockInfo.allLocks[i];
// For the emergency unlock situation, lFPIS = FPIS
if (_isEmergencyUnlockActive) {
_expectedLFPIS += uint256(int256(_lockInfo.amount));
} else {
// Get the lock time to use
uint128 _lockSecsToUse;
if (_lockInfo.end < uint128(block.timestamp)) {
_lockSecsToUse = 0;
} else {
_lockSecsToUse = _lockInfo.end - uint128(block.timestamp);
}
// Get the approximate lFPIS
_expectedLFPIS += getCrudeExpectedLFPISOneLock(_lockInfo.amount, _lockSecsToUse);
}
unchecked {
++i;
}
}
}
}
// src/contracts/VestedFXS-and-Flox/VestedFXS/VeFXSYieldDistributor.sol
// ====================================================================
// | ______ _______ |
// | / _____________ __ __ / ____(_____ ____ _____ ________ |
// | / /_ / ___/ __ `| |/_/ / /_ / / __ \/ __ `/ __ \/ ___/ _ \ |
// | / __/ / / / /_/ _> < / __/ / / / / / /_/ / / / / /__/ __/ |
// | /_/ /_/ \__,_/_/|_| /_/ /_/_/ /_/\__,_/_/ /_/\___/\___/ |
// | |
// ====================================================================
// =======================veFXSYieldDistributor========================
// ====================================================================
// Distributes Frax protocol yield based on the claimer's veFXS balance
// Yield will now not accrue for unlocked veFXS
// Frax Finance: https://github.com/FraxFinance
// Primary Author(s)
// Jan Turk: https://github.com/ThunderDeliverer
// Travis Moore: https://github.com/FortisFortuna
// Reviewer(s) / Contributor(s)
// Sam Kazemian: https://github.com/samkazemian
// Originally inspired by Synthetix.io, but heavily modified by the Frax team (veFXS portion)
// https://github.com/Synthetixio/synthetix/blob/develop/contracts/StakingRewards.sol
contract VeFXSYieldDistributor is OwnedV2AutoMsgSender, ReentrancyGuard, IveFXSStructs {
using SafeERC20 for ERC20;
// ==============================================================================
// STATE VARIABLES
// ==============================================================================
// Instances
// -------------------------
/// @notice The FPIS Locker contract
IFPISLocker public fpisLocker;
/// @notice The IL1VeFXS contract (snapshot of Ethereum Mainnet veFXS.vy)
IL1VeFXS public l1veFXS;
/// @notice The Fraxtal veFXS contract
IVestedFXS public veFXS;
/// @notice The Fraxtal veFXS veFXSUtils contract
IVestedFXSUtils public veFXSUtils;
/// @notice The Fraxtal FPIS Locker FPISLockerUtils contract
FPISLockerUtils public lFpisUtils;
/// @notice Oracle on Fraxtal that reports Mainnet veFXS totalSupply.
L1VeFXSTotalSupplyOracle public l1VeFXSTotalSupplyOracle;
/// @notice ERC20 instance of the token being emitted
ERC20 public emittedToken;
// Addresses
// -------------------------
/// @notice Address of the token being emitted
address public emittedTokenAddress;
/// @notice Address of the timelock
address public timelockAddress;
/// @notice Array of additional / future veFXS-like contracts
address[] public addlVeContractsArr;
/// @notice Whether an address is an additional / future veFXS-like contract
mapping(address => bool) public addlVeContracts;
// Yield and period related
// -------------------------
/// @notice Timestamp when the reward period ends
uint256 public periodFinish;
/// @notice Timestamp when the contract was last synced or had rewards deposited
uint256 public lastUpdateTime;
/// @notice Emission rate of tokens, in tokens per second
uint256 public yieldRate;
/// @notice Duration of the period, in seconds
uint256 public yieldDuration; // 7 * 86400 (7 days)
/// @notice Mapping of addresses that are allowed to deposit reward tokens
mapping(address => bool) public rewardNotifiers;
// Yield tracking
// -------------------------
/// @notice Accumulator for tracking contract-wide rewards paid
uint256 public yieldPerVeFXSStored;
/// @notice Accumulator for tracking user-specific rewards paid
mapping(address => uint256) public userYieldPerTokenPaid;
/// @notice Last stored version of earned(). Set to 0 on yield claim and to earned() on a checkpoint.
mapping(address => uint256) public yields;
// veFXS tracking
// -------------------------
/// @notice Total amount of veFXS that was checkpointed and is earning
uint256 public totalVeFXSParticipating;
/// @notice Stored version of the total veFXS supply
uint256 public totalComboVeFXSSupplyStored;
/// @notice If the user was initialized or not
mapping(address => bool) public userIsInitialized;
/// @notice Last stored veFXS balance for the user
mapping(address => uint256) public userVeFXSCheckpointed;
/// @notice The stored shortest endpoint of any of the user's veFXS positions. You will need to re-checkpoint after any lock expires if you want to keep earning.
mapping(address => uint256) public userVeFXSEndpointCheckpointed;
/// @notice Last time the user claimed their yield
mapping(address => uint256) private lastRewardClaimTime; // staker addr -> timestamp
// Greylists
// -------------------------
/// @notice A graylist for questionable users
mapping(address => bool) public greylist;
// Constants
// -------------------------
/// @notice Constant for price precision
uint256 private constant PRICE_PRECISION = 1e6;
// Admin booleans for emergencies
// -------------------------
/// @notice A graylist for questionable users
bool public yieldCollectionPaused = false; // For emergencies
/// @dev reserve extra storage for future upgrades
uint256[50] private __gap;
// ==============================================================================
// MODIFIERS
// ==============================================================================
/// @notice A modifier that only allows the contract owner or the timelock to call
modifier onlyByOwnGov() {
if (msg.sender != owner && msg.sender != timelockAddress) revert NotOwnerOrTimelock();
_;
}
/// @notice Make sure yield collection is not paused
modifier notYieldCollectionPaused() {
if (yieldCollectionPaused) revert YieldCollectionPaused();
_;
}
/// @notice Checkpoint the user
modifier checkpointUser(address account) {
_checkpointUser(account);
_;
}
// ==============================================================================
// CONSTRUCTOR
// ==============================================================================
constructor() {}
/**
* @notice Initialize contract
* @param _owner The owner of this contract
* @param _timelockAddress Address of the timelock
* @param _emittedToken Address of the token being emitted as yield
* @param _veAddresses The addresses: 0: veFXS, 1: veFXSUtils, 2: FPIS Locker, 3: FPISLockerUtils, 4: L1VeFXS, 5: L1VeFXSTotalSupplyOracle
*/
function initialize(
address _owner,
address _timelockAddress,
address _emittedToken,
address[6] memory _veAddresses
) public {
// Safety checks - no validation on admin in case this is initialized without admin
if (_emittedToken == address(0) || emittedTokenAddress != address(0)) {
revert InitializeFailed();
}
// Set owner for OwnedV2
owner = _owner;
// Set misc addresses
emittedTokenAddress = _emittedToken;
emittedToken = ERC20(_emittedToken);
timelockAddress = _timelockAddress;
// Set the Fraxtal VestedFXS
veFXS = IVestedFXS(_veAddresses[0]);
veFXSUtils = IVestedFXSUtils(_veAddresses[1]);
// (Optional) Set the FPISLocker
if ((_veAddresses[2] != address(0)) && (_veAddresses[3] != address(0))) {
fpisLocker = IFPISLocker(_veAddresses[2]);
lFpisUtils = FPISLockerUtils(_veAddresses[3]);
}
// (Optional) Set the L1VeFXS andL1VeFXSTotalSupplyOracle
if ((_veAddresses[4] != address(0)) && (_veAddresses[5] != address(0))) {
l1veFXS = IL1VeFXS(_veAddresses[4]);
l1VeFXSTotalSupplyOracle = L1VeFXSTotalSupplyOracle(_veAddresses[5]);
}
// Initialize other variables
lastUpdateTime = block.timestamp;
rewardNotifiers[_owner] = true;
yieldDuration = 604_800;
}
// ==============================================================================
// VIEWS
// ==============================================================================
/// @notice Fraction of the total Fraxtal-visible veFXS collecting yield
/// @return _fraction The Fraction
function fractionParticipating() external view returns (uint256 _fraction) {
if (totalComboVeFXSSupplyStored == 0) return 0;
else return (totalVeFXSParticipating * PRICE_PRECISION) / totalComboVeFXSSupplyStored;
}
/// @notice Total veFXS of a user from multiple different sources, such as the FPIS Locker, L1VeFXS, and Fraxtal veFXS
/// @param _user The user to check
/// @return _currBal The veFXS balance
function ttlCombinedVeFXS(address _user) public view returns (uint256 _currBal) {
// Look at the OG 3 sources first
// ===========================
// VestedFXS on Fraxtal
_currBal = veFXS.balanceOf(_user);
// (Optional) FPIS Locker on Fraxtal
if (address(fpisLocker) != address(0)) _currBal += fpisLocker.balanceOf(_user);
// (Optional) L1VeFXS: snapshot of Ethereum Mainnet veFXS. Lives on Fraxtal
if ((address(l1veFXS) != address(0)) && (address(l1VeFXSTotalSupplyOracle) != address(0))) {
_currBal += l1veFXS.balanceOf(_user);
}
// (Optional) Look at any extra veFXS sources
for (uint256 i = 0; i < addlVeContractsArr.length; i++) {
address _veAddr = addlVeContractsArr[i];
if (_veAddr != address(0)) {
_currBal += IVestedFXS(_veAddr).balanceOf(_user);
}
}
}
/// @notice Total veFXS totalSupply from multiple different sources, such as the FPIS Locker, L1VeFXS, and Fraxtal veFXS. Non-checkpointed L1VeFXS is excluded
/// @return _totalSupply The veFXS totalSupply from all sources
function ttlCombinedVeFXSTotalSupply() public view returns (uint256 _totalSupply) {
// Look at the OG 3 sources first
// ===========================
// VestedFXS on Fraxtal
_totalSupply = veFXS.totalSupply();
// (Optional) FPIS Locker on Fraxtal
if (address(fpisLocker) != address(0)) _totalSupply += fpisLocker.totalSupply();
// (Optional) L1VeFXS: snapshot of Ethereum Mainnet veFXS. Lives on Fraxtal
if ((address(l1veFXS) != address(0)) && (address(l1VeFXSTotalSupplyOracle) != address(0))) {
_totalSupply += l1VeFXSTotalSupplyOracle.totalSupply();
}
// (Optional) Look at any extra veFXS sources
for (uint256 i = 0; i < addlVeContractsArr.length; i++) {
address _veAddr = addlVeContractsArr[i];
if (_veAddr != address(0)) {
_totalSupply += IVestedFXS(_veAddr).totalSupply();
}
}
}
/// @notice Eligible veFXS for a given user. Only positions with locked veFXS can accrue yield, not expired positions
/// @param _user The user to check
/// @return _eligibleVefxsBal Eligible veFXS
/// @return _storedEndingTimestamp The stored ending timestamp
function eligibleCurrentVeFXS(
address _user
) public view returns (uint256 _eligibleVefxsBal, uint256 _storedEndingTimestamp) {
// Get the total combined veFXS from all sources
uint256 _currVefxsBal = ttlCombinedVeFXS(_user);
// Stored is used to prevent abuse
_storedEndingTimestamp = userVeFXSEndpointCheckpointed[_user];
// Only unexpired veFXS should be eligible
if (block.timestamp >= _storedEndingTimestamp) {
_eligibleVefxsBal = 0;
} else {
_eligibleVefxsBal = _currVefxsBal;
}
}
/// @notice Last time the yield was accruing
/// @return _ts The timestamp
function lastTimeYieldApplicable() public view returns (uint256 _ts) {
return (block.timestamp < periodFinish ? block.timestamp : periodFinish);
}
/// @notice Amount of yield per veFXS
/// @return _yield The amount of yield
function yieldPerVeFXS() public view returns (uint256 _yield) {
if (totalComboVeFXSSupplyStored == 0) {
return yieldPerVeFXSStored;
} else {
return (yieldPerVeFXSStored +
(((lastTimeYieldApplicable() - lastUpdateTime) * yieldRate * 1e18) / totalComboVeFXSSupplyStored));
}
}
/// @notice Amount of tokens claimaible as yield
/// @param _account The user to check
/// @return _earned The amount of yield
function earned(address _account) public view returns (uint256 _earned) {
// Uninitialized users should not earn anything yet
// console2.log("userIsInitialized[_account]: ", userIsInitialized[_account]);
if (!userIsInitialized[_account]) return 0;
// Get eligible veFXS balances
(uint256 eligibleCurrentVefxs, uint256 endingTimestamp) = eligibleCurrentVeFXS(_account);
// If your veFXS is unlocked
uint256 eligibleTimeFraction = PRICE_PRECISION;
// console2.log("eligibleTimeFraction: ", eligibleTimeFraction);
if (eligibleCurrentVefxs == 0) {
// console2.log("block.timestamp: ", block.timestamp);
// console2.log("lastRewardClaimTime[_account]: ", lastRewardClaimTime[_account]);
// console2.log("endingTimestamp: ", endingTimestamp);
// And you already claimed after expiration
if (lastRewardClaimTime[_account] >= endingTimestamp) {
// You get NOTHING. You LOSE. Good DAY ser!
return 0;
}
// You haven't claimed yet
else {
// See what fraction of the time since you last claimed that you were eligible for earning
// console2.log("calculating eligibleTimeFraction");
uint256 eligibleTime = endingTimestamp - lastRewardClaimTime[_account];
// console2.log("eligibleTime: ", eligibleTime);
uint256 totalTime = block.timestamp - lastRewardClaimTime[_account];
// console2.log("totalTime: ", totalTime);
eligibleTimeFraction = (PRICE_PRECISION * eligibleTime) / totalTime;
// console2.log("eligibleTimeFraction: ", eligibleTimeFraction);
}
}
// If the amount of veFXS increased, only pay off based on the old balance
// Otherwise, take the midpoint
uint256 vefxsBalanceToUse;
uint256 oldVefxsBalance = userVeFXSCheckpointed[_account];
// console2.log("vefxsBalanceToUse: ", vefxsBalanceToUse);
// console2.log("oldVefxsBalance: ", oldVefxsBalance);
if (eligibleCurrentVefxs > oldVefxsBalance) {
// VeFXS increased so use old amount
vefxsBalanceToUse = oldVefxsBalance;
// console2.log("VeFXS increased so use old amount: ", vefxsBalanceToUse);
} else {
// VeFXS decreased so use midpoint (average)
vefxsBalanceToUse = (eligibleCurrentVefxs + oldVefxsBalance) / 2;
// console2.log("VeFXS decreased so use midpoint (average): ", vefxsBalanceToUse);
// Print old earnings if there was no midpointing (debug only)
uint256 _oldVeFXSEarnings = ((oldVefxsBalance *
(yieldPerVeFXS() - userYieldPerTokenPaid[_account]) *
eligibleTimeFraction) /
(1e18 * PRICE_PRECISION) +
yields[_account]);
// console2.log("Old earnings would have been: ", _oldVeFXSEarnings);
}
// Calculate earnings
return ((vefxsBalanceToUse * (yieldPerVeFXS() - userYieldPerTokenPaid[_account]) * eligibleTimeFraction) /
(1e18 * PRICE_PRECISION) +
yields[_account]);
}
/// @notice Total amount of yield for the duration (normally a week)
/// @return _yield The amount of yield
function getYieldForDuration() external view returns (uint256 _yield) {
return (yieldRate * yieldDuration);
}
/// @notice Array of all extra veFXS-like contracts
/// @return _addresses The addresses
function allAddlVeContractsAddreses() external view returns (address[] memory _addresses) {
return addlVeContractsArr;
}
/// @notice Length of the array of all extra veFXS-like contracts
/// @return _length The length
function allAddlVeContractsLength() external view returns (uint256 _length) {
return addlVeContractsArr.length;
}
/// @notice Get all the active locks for a user
/// @param _account The account to get the locks for
/// @return _currActiveLocks Array of LockedBalanceExtended structs (all active locks)
function getAllCurrActiveLocks(
address _account
) public view returns (LockedBalanceExtended[] memory _currActiveLocks) {
// Prepare to allocate the return array. Not all of the locks will be active.
// OG 3 veFXS contracts
// ===================================
// Fraxtal VestedFXS
uint256 _maxArrSize = veFXS.numLocks(_account);
// (Optional) FPIS Locker
if (address(fpisLocker) != address(0)) _maxArrSize += fpisLocker.numLocks(_account);
// (Optional) L1VeFXS
if ((address(l1veFXS) != address(0)) && (address(l1VeFXSTotalSupplyOracle) != address(0))) {
_maxArrSize += 1; // Legacy veFXS on Mainnet only has one lock
}
// (Optional) Get the total number of locks in the additional veFXS contracts
for (uint256 i = 0; i < addlVeContractsArr.length; i++) {
address _veAddr = addlVeContractsArr[i];
if (_veAddr != address(0)) {
// Get the total number of locks
_maxArrSize += IVestedFXS(_veAddr).numLocks(_account);
}
}
// Allocate a temporary dynamic array
uint256 _activeLockIdx = 0;
LockedBalanceExtended[] memory _tmpActiveLocks = new LockedBalanceExtended[](_maxArrSize);
// Go through the OG 3 sources first
// Fraxtal veFXS
// -------------------------
{
// Get the LockedBalanceExtendeds
LockedBalanceExtended[] memory _fxtlVeFXSLockedBalExtds = (veFXSUtils.getDetailedUserLockInfo(_account))
.activeLocks;
// Loop though the Fraxtal veFXS locks and add them to the combined array
for (uint256 i; i < _fxtlVeFXSLockedBalExtds.length; ) {
// Save tmp variable to memory
IveFXSStructs.LockedBalanceExtended memory _vestedFXSLockInfo = _fxtlVeFXSLockedBalExtds[i];
// Double check that the end time is in the future
// if (_vestedFXSLockInfo.end > block.timestamp) {
_tmpActiveLocks[_activeLockIdx] = _vestedFXSLockInfo;
// Increase the active lock index
++_activeLockIdx;
// }
unchecked {
++i;
}
}
}
// (Optional) FPIS Locker
// -------------------------
if (address(fpisLocker) != address(0)) {
// Get the LockedBalanceExtendeds
IlFPISStructs.LockedBalanceExtended[] memory _fpisLockerLockedBalExtds = (
lFpisUtils.getDetailedUserLockInfo(_account)
).activeLocks;
// Loop though the FPIS Locker locks and add them to the combined array
for (uint256 i; i < _fpisLockerLockedBalExtds.length; ) {
// Save tmp variable to memory
IlFPISStructs.LockedBalanceExtended memory _fpisLockInfo = _fpisLockerLockedBalExtds[i];
// Double check end time
if (_fpisLockInfo.end > block.timestamp) {
// Need to cast to IveFXSStruct's version of LockedBalanceExtended for compiling
_tmpActiveLocks[_activeLockIdx] = IveFXSStructs.LockedBalanceExtended({
id: _fpisLockInfo.id,
index: _fpisLockInfo.index,
amount: _fpisLockInfo.amount,
end: _fpisLockInfo.end
});
// Increase the active lock index
++_activeLockIdx;
}
unchecked {
++i;
}
}
}
// (Optional) L1VeFXS
// -------------------------
if ((address(l1veFXS) != address(0)) && (address(l1VeFXSTotalSupplyOracle) != address(0))) {
// Get the LockedBalance
IL1VeFXS.LockedBalance memory _l1LockedBalance = l1veFXS.locked(_account);
// Convert to LockedBalanceExtended and push into _currCombinedLockBalExtds if it is active. There is only one lock too
if (_l1LockedBalance.end > block.timestamp) {
_tmpActiveLocks[_activeLockIdx] = LockedBalanceExtended({
id: 0,
index: 0,
amount: int128(_l1LockedBalance.amount),
end: _l1LockedBalance.end
});
// Increase the active lock index
++_activeLockIdx;
}
}
// (Optional) Look in the extra veFXS sources next. They should all be IVestedFXS ABI compliant
for (uint256 i = 0; i < addlVeContractsArr.length; i++) {
address _veAddr = addlVeContractsArr[i];
if (_veAddr != address(0)) {
// Get the active locks
LockedBalanceExtended[] memory _addlVeFXSLockedBalExtds = (
IVestedFXSUtils(IVestedFXS(_veAddr).veFxsUtils()).getDetailedUserLockInfo(_account)
).activeLocks;
// Loop though the active locks and add them to the combined array
for (uint256 i; i < _addlVeFXSLockedBalExtds.length; ) {
// Save tmp variable to memory
IveFXSStructs.LockedBalanceExtended memory _addVeFXSLockInfo = _addlVeFXSLockedBalExtds[i];
// // Double check that the end time is in the future
// if (_addVeFXSLockInfo.end > block.timestamp) {
_tmpActiveLocks[_activeLockIdx] = _addVeFXSLockInfo;
// Increase the active lock index
++_activeLockIdx;
// }
unchecked {
++i;
}
}
}
}
// Allocate the return array with only the number of active locks
_currActiveLocks = new LockedBalanceExtended[](_activeLockIdx);
// Fill the return array
for (uint256 i; i < _currActiveLocks.length; ) {
_currActiveLocks[i] = _tmpActiveLocks[i];
unchecked {
++i;
}
}
}
// ==============================================================================
// MUTATIVE FUNCTIONS
// ==============================================================================
/// @notice Checkpoint a user's earnings
/// @param _account The user to checkpoint
/// @dev If you want to keep earning, you need to make sure you checkpoint after ANY lock expires
function _checkpointUser(address _account) internal {
// Need to retro-adjust some things if the period hasn't been renewed, then start a new one
sync();
// Calculate the earnings first
_syncEarned(_account);
// Get the old and the new veFXS balances
uint256 _oldVefxsBalance = userVeFXSCheckpointed[_account];
// Get the total combined veFXS from all sources
uint256 _newVefxsBalance = ttlCombinedVeFXS(_account);
// Update the user's stored veFXS balance
userVeFXSCheckpointed[_account] = _newVefxsBalance;
// Collect all active locks
LockedBalanceExtended[] memory _currCombinedLockBalExtds = getAllCurrActiveLocks(_account);
// Update the user's stored ending timestamp
// TODO: Check this math as well as corner cases
// TODO: Is there a better way to do this? This might be ok for now since gas is low on Fraxtal, but in the future,
// I imagine there is a more elegant solution
// ----------------------
uint128 _shortestActiveLockEnd;
// In case there are no active locks anywhere
if (_currCombinedLockBalExtds.length > 0) {
// console2.log("_checkpointUser > 0 active locks");
_shortestActiveLockEnd = _currCombinedLockBalExtds[0].end;
}
// Find the timestamp of the lock closest to expiry
if (_currCombinedLockBalExtds.length > 1) {
// console2.log("_checkpointUser > 1 active locks");
for (uint256 i; i < _currCombinedLockBalExtds.length; ) {
// console2.log("_currCombinedLockBalExtds[i].end: ", _currCombinedLockBalExtds[i].end);
if (_currCombinedLockBalExtds[i].end < _shortestActiveLockEnd) {
_shortestActiveLockEnd = _currCombinedLockBalExtds[i].end;
}
unchecked {
++i;
}
}
}
// console2.log("userVeFXSEndpointCheckpointed result: ", _shortestActiveLockEnd);
userVeFXSEndpointCheckpointed[_account] = _shortestActiveLockEnd;
// Update the total amount participating
if (_newVefxsBalance >= _oldVefxsBalance) {
uint256 weightDiff = _newVefxsBalance - _oldVefxsBalance;
totalVeFXSParticipating = totalVeFXSParticipating + weightDiff;
} else {
uint256 weightDiff = _oldVefxsBalance - _newVefxsBalance;
totalVeFXSParticipating = totalVeFXSParticipating - weightDiff;
}
// Mark the user as initialized
if (!userIsInitialized[_account]) {
userIsInitialized[_account] = true;
lastRewardClaimTime[_account] = block.timestamp;
}
}
/// @notice Sync a user's earnings
/// @param _account The user to sync
function _syncEarned(address _account) internal {
if (_account != address(0)) {
uint256 earned0 = earned(_account);
yields[_account] = earned0;
userYieldPerTokenPaid[_account] = yieldPerVeFXSStored;
}
}
/// @notice Anyone can checkpoint another user
/// @param _account The user to sync
function checkpointOtherUser(address _account) external {
_checkpointUser(_account);
}
/// @notice Checkpoint yourself
function checkpoint() external {
_checkpointUser(msg.sender);
}
/// @notice Anyone can checkpoint another user
/// @return _yield0 The amount collected
function getYield()
external
nonReentrant
notYieldCollectionPaused
checkpointUser(msg.sender)
returns (uint256 _yield0)
{
if (greylist[msg.sender]) revert AddressGreylisted();
_yield0 = yields[msg.sender];
if (_yield0 > 0) {
yields[msg.sender] = 0;
TransferHelper.safeTransfer(emittedTokenAddress, msg.sender, _yield0);
emit YieldCollected(msg.sender, _yield0, emittedTokenAddress);
}
lastRewardClaimTime[msg.sender] = block.timestamp;
}
/// @notice Sync contract-wide variables
function sync() public {
// Update the yieldPerVeFXSStored
// console2.log("Update the yieldPerVeFXSStored");
yieldPerVeFXSStored = yieldPerVeFXS();
// Update the total veFXS supply
// console2.log("Update the totalComboVeFXSSupplyStored");
totalComboVeFXSSupplyStored = ttlCombinedVeFXSTotalSupply();
// Update the last update time
// console2.log("Update the lastUpdateTime");
lastUpdateTime = lastTimeYieldApplicable();
// console2.log("Sync completed");
}
/// @notice Deposit rewards. Only callable by privileged users
/// @param _amount The amount to deposit
function notifyRewardAmount(uint256 _amount) external {
// Only whitelisted addresses can notify rewards
if (!rewardNotifiers[msg.sender]) revert SenderNotRewarder();
// Handle the transfer of emission tokens via `transferFrom` to reduce the number
// of transactions required and ensure correctness of the smission amount
emittedToken.safeTransferFrom(msg.sender, address(this), _amount);
// Update some values beforehand
sync();
// Update the new yieldRate
if (block.timestamp >= periodFinish) {
yieldRate = _amount / yieldDuration;
} else {
uint256 remaining = periodFinish - block.timestamp;
uint256 leftover = remaining * yieldRate;
yieldRate = (_amount + leftover) / yieldDuration;
}
// Update duration-related info
lastUpdateTime = block.timestamp;
periodFinish = block.timestamp + yieldDuration;
// Update some values afterwards
totalComboVeFXSSupplyStored = ttlCombinedVeFXSTotalSupply();
emit RewardAdded(_amount, yieldRate);
}
// ==============================================================================
// RESTRICTED FUNCTIONS
// ==============================================================================
/// @notice Adds an additional veFXS-like contract
/// @param _addr The contract to added
function addAddlVeFXSContract(address _addr) public onlyByOwnGov {
// Future upgrade: remove this once full support is added and tested
require(false, "Cannot add/remove additional veFXS sources yet");
require(_addr != address(0), "Zero address detected");
// TODO: Check the ABI here to make sure it is veFXS-like
require(IVestedFXS(_addr).totalSupply() >= 0, "No totalSupply() function");
require(IVestedFXS(_addr).balanceOf(address(0)) >= 0, "No balanceOf() function");
// These should not revert
IVestedFXSUtils(IVestedFXS(_addr).veFxsUtils()).getDetailedUserLockInfo(address(0));
require(addlVeContracts[_addr] == false, "Address already exists");
addlVeContracts[_addr] = true;
addlVeContractsArr.push(_addr);
sync();
emit AddlVeFXSContractAdded(_addr);
}
/// @notice Removes a veFXS-like contract
/// @param _addr The contract to remove
function removeAddlVeFXSContract(address _addr) public onlyByOwnGov {
// Future upgrade: remove this once full support is added and tested
require(false, "Cannot add/remove additional veFXS sources yet");
require(_addr != address(0), "Zero address detected");
require(addlVeContracts[_addr] == true, "Address nonexistent");
// Delete from the mapping
delete addlVeContracts[_addr];
// 'Delete' from the array by setting the address to 0x0
for (uint256 i = 0; i < addlVeContractsArr.length; i++) {
if (addlVeContractsArr[i] == _addr) {
addlVeContractsArr[i] = address(0); // This will leave a null in the array and keep the indices the same
break;
}
}
sync();
emit AddlVeFXSContractRemoved(_addr);
}
/// @notice Added to support recovering LP Yield and other mistaken tokens from other systems to be distributed to holders
/// @param _tokenAddress The token to recover
/// @param _tokenAmount The amount to recover
function recoverERC20(address _tokenAddress, uint256 _tokenAmount) external onlyByOwnGov {
// Only the owner address can ever receive the recovery withdrawal
TransferHelper.safeTransfer(_tokenAddress, owner, _tokenAmount);
emit RecoveredERC20(_tokenAddress, _tokenAmount);
}
/// @notice Set the duration of the yield
/// @param _yieldDuration New duration in seconds
function setYieldDuration(uint256 _yieldDuration) external onlyByOwnGov {
if (periodFinish != 0 && block.timestamp <= periodFinish) {
revert YieldPeriodMustCompleteBeforeChangingToNewPeriod();
}
yieldDuration = _yieldDuration;
emit YieldDurationUpdated(yieldDuration);
}
/// @notice Greylist an address that is misbehaving
/// @param _address The address to greylist
function greylistAddress(address _address) external onlyByOwnGov {
greylist[_address] = !(greylist[_address]);
}
/// @notice Toggle an address as being able to be a reward notifier
/// @param _notifierAddr The address to toggle
function toggleRewardNotifier(address _notifierAddr) external onlyByOwnGov {
rewardNotifiers[_notifierAddr] = !rewardNotifiers[_notifierAddr];
}
/// @notice Set the original 3 veFXS-like contracts on Fraxtal
/// @param _veAddresses The addresses: 0: veFXS, 1: veFXSUtils, 2: FPIS Locker, 3: FPISLockerUtils, 4: L1VeFXS, 5: L1VeFXSTotalSupplyOracle
function setAddresses(address[6] calldata _veAddresses) external onlyByOwnGov {
// Future upgrade: remove this once full support is added and tested
require(_veAddresses[0] != address(0), "veFXS must not be 0x0");
require(_veAddresses[1] != address(0), "veFXSUtils must not be 0x0");
require(_veAddresses[2] == address(0), "Cannot add FPISLocker yet");
require(_veAddresses[3] == address(0), "Cannot add FPISLockerUtils yet");
require(_veAddresses[4] == address(0), "Cannot add L1VeFXS yet");
require(_veAddresses[5] == address(0), "Cannot add L1VeFXSTotalSupplyOracle yet");
// Set veFXS-like addresses
veFXS = IVestedFXS(_veAddresses[0]);
veFXSUtils = IVestedFXSUtils(_veAddresses[1]);
// FPIS Locker
if ((_veAddresses[2] != address(0)) && _veAddresses[3] != address(0)) {
fpisLocker = IFPISLocker(_veAddresses[2]);
lFpisUtils = FPISLockerUtils(_veAddresses[3]);
}
// L1VeFXS and L1VeFXSTotalSupplyOracle
if ((_veAddresses[4] != address(0)) && (_veAddresses[5] != address(0))) {
l1veFXS = IL1VeFXS(_veAddresses[4]);
l1VeFXSTotalSupplyOracle = L1VeFXSTotalSupplyOracle(_veAddresses[5]);
}
}
/// @notice Pause / unpause yield collecting
/// @param _yieldCollectionPaused The new status
function setPauses(bool _yieldCollectionPaused) external onlyByOwnGov {
yieldCollectionPaused = _yieldCollectionPaused;
}
/// @notice Used for manual reward rates. Only valid until the next notifyRewardAmount() or setYieldRate()
/// @param _newRate The new rate
/// @param _syncToo Whether to sync or not
function setYieldRate(uint256 _newRate, bool _syncToo) external onlyByOwnGov {
yieldRate = _newRate;
if (_syncToo) {
sync();
}
}
/// @notice Set the timelock address
/// @param _newTimelock The address of the timelock
function setTimelock(address _newTimelock) external onlyByOwnGov {
timelockAddress = _newTimelock;
}
// ==============================================================================
// EVENTS
// ==============================================================================
/// @notice When an additional veFXS contract is added
/// @param addr The contract that was added
event AddlVeFXSContractAdded(address addr);
/// @notice When an additional veFXS contract is removed
/// @param addr The contract that was removed
event AddlVeFXSContractRemoved(address addr);
/// @notice When the contract is initialized
event DefaultInitialization();
/// @notice When ERC20 tokens were recovered
/// @param token Token address
/// @param amount Amount of tokens collected
event RecoveredERC20(address token, uint256 amount);
/// @notice When a reward is deposited
/// @param reward Amount of tokens deposited
/// @param yieldRate The resultant yield/emission rate
event RewardAdded(uint256 reward, uint256 yieldRate);
/// @notice When yield is collected
/// @param user Address collecting the yield
/// @param yield The amount of tokens collected
/// @param tokenAddress The address collecting the rewards
event YieldCollected(address indexed user, uint256 yield, address tokenAddress);
/// @notice When the yield duration is updated
/// @param newDuration The new duration
event YieldDurationUpdated(uint256 newDuration);
// ==============================================================================
// ERRORS
// ==============================================================================
/// @notice If the address was greylisted
error AddressGreylisted();
/// @notice Cannot initialize twice
error InitializeFailed();
/// @notice If you are trying to call a function not as the owner or timelock
error NotOwnerOrTimelock();
/// @notice If the sender is not a rewarder
error SenderNotRewarder();
/// @notice If yield collection is paused
error YieldCollectionPaused();
/// @notice If you are trying to change a yield period before it ends
error YieldPeriodMustCompleteBeforeChangingToNewPeriod();
/* ====================================== A NIFFLER ================================================ */
// MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMWWWMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
// MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMN0OxdOKKOOkxxxxxxk0XWMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
// MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMN0dl:,',cc:;;;;;;;;,'';cx0XWMMMMMMMMMMMMMMMMMMMMMMMMMMM
// MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMWXkl:;::::::::::;;;;:::::;;,;cox0NWMMMMMMMMMMMMMMMMMMMMMMM
// MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMXxc;;:;;;;;;;,;,,,,,,,,,;,,,,,,,,;cdOXMMMMMMMMMMMMMMMMMMMMM
// MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMWOc;;;,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,'.;d0NMMMMMMMMMMMMMMMMMM
// MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMXd;;:;,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,'',l0WMMMMMMMMMMMMMMMMM
// MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMXo;;;,,,,,,,,,,,,,,,,,,,,,,''''''',,,,,,,,,,ckNMMMMMMMMMMMMMMMM
// MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMNd;;,,,,,,,,,,,,,,,,,,,,,,,'''''...'',,,,,,,,,,l0WMMMMMMMMMMMMMM
// MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMO;,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,'''''',,,,,,,'.'xNMMMMMMMMMMMMM
// MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMNo',,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,'.'kWMMMMMMMMMMMM
// MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM0:',,,,,,,,,,,,,,,;;;,,,,,,,,,,,,,,,,,,,,,,,,,,,,''lKMMMMMMMMMMMM
// MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMO;',,;;,,,,,,,;:cc:;:c;,,,,,,,,,,,,,,,,,,,,,,,,,,,,'c0WMMMMMMMMMM
// MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMk,';lkkxoc;,,,cxl,...cl,,,,,,,,,,,,,,,,,,,,,,,,,,,,'':OWMMMMMMMMM
// MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMWx;cx00000OkdooxOd;',;ll,,,,,,,,,,,,,,,,,,,,,,,,,,,,,'.;OWMMMMMMMM
// MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMWKOxdxO00000000000000Oxxxd:,,''',,,,,,,,,,,,,,,,,,,,,,,,'..,OWMMMMMMM
// MMMMMMMMMMMMMMMMMMMMWKkkOO00OOkxxxO00000000000000000Okddd:.....'''''',,,,,,,,,,,,,,,,,,,'..oNMMMMMMM
// MMMMMMMMMMMMMMMMMMMM0ookkxxxdxk00000000000000000Okkkxxdl;............',,,,,,,,,,,,,,,,,,'..;OMMMMMMM
// MMMMMMMMMMMMMMMMMMMMKdoxOOOO000000000000000Okkxdollc:;'.....''..''....',,,,,,,,,,,,,,,,,,'..;KMMMMMM
// MMMMMMMMMMMMMMMMMMMMMNOxddodddxxxxxxxxddoll:,,,,,'''''''.'',,''',,'','',,,,,,,,,,,,,,,,,,,'..dNMMMMM
// MMMMMMMMMMMMMMMMMMMMMMMMNXK0OOOkkkkkkkOkdc;'.',,,,,,''''',,,,,,,,,,,,,,,,,,,,,',,,,,,,,,,,,.,xNMMMMM
// MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMWNKko:;:lodxxxxxdolc;,,,,,,,,,,,,,,,,,,,'''',,,,,,,,,,,,''dWMMMMM
// MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMWKkddl:lxO000000000000Odc;,,,,,,,,,,,,,,'.',,,,,,,,,,,,,,,,.:KMMMMM
// MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMW0odO0kooxO00000000000000Oxl:::::::;;;::,.',,,,,,,,,,,,,,,,,',kMMMMM
// MMMMMMMMMMMMMMMMMMMMMMMMMMMMMWWNXdlk0kdodO000000000000000kxdxOOOOOkkkkOkxc,',,,,,,,,,,,,,,,,'.dWMMMM
// MMMMMMMMMMMMMMMMMMMMMMMMWNKkdoccol:loc:;:lllllllooddxkOOOdllok0OO0000000Od;',,,,,,,,,,,,,,,,'.lNMMMM
// MMMMMMMMMMMMMMMMMMMMMMMKl:c::c:;,,','',,,,,,,,,,,,,,,;:cllcc::::::clodxxdc,',,,'''..'',,,,,,'.cXMMMM
// MMMMMMMMMMMMMMMMMMMMMMXo:clc:;,,,,,,,,,,,,,,,,,,,,,,,,,,,,;;,''''''''''''..........',,,,,,,,..cXMMMM
// MMMMMMMMMMMMMMMMMMMMMMOlol,'',,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,''''''''....''''''',,,,,,,,,,,,,..lNMMMM
// MMMMMMMMMMMMMMMMMMMMMMk:;,,,,,,,,,,,,,,,,,,,,,,,:,',,,,,,,''..............'',,,,,,,,,,,,,,,,..dWMMMM
// MMMMWWWMWWMMMMMMMMMMMXl'',,,,,,,,,,,,,,,,;:;:olcdocl:'''.....'',,,,,,''',''..',,,,,,,,,,,,,'.;0MMMMM
// MMMMXdlxllkXWMNXWMMMNo..,,,,,,,,,,,,,,,,,:oxoxkxkOOOl'....'',,,,,,,,,,,,,,,,'.'',,,,,,,,,,'..oWMMMMM
// MMMMWk,...';ldc,lxk0k;.',,,,,,,,,,,,,,,,,;ckOOO00000l..'',,,,,,,,,,,,,,,,,,,,,'',,,,,,,,,,..'kMMMMMM
// MMMMMNl..,,,,'''''',,'....'',,,,,,,,,,,,cook0000000Oc..',,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,'..;0MMMMMM
// MMMMMMO...',,,,,,,,,,,'.'''..''',,,,,,,,lkkO000000Ox;.',,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,...lNMMMMMM
// MMMMMMNl....'',,,,,,,,,,,,,,''''..',,,,;dkO00000xlc:,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,'..'kMMMMMMM
// MMMMMMMk'....',,,,,,,,,,,,,,,,,''..'',,:xkO000Oxc,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,'...cXMMMMMMM
// MMMMMMMX:....'',,,,,,,,,,,,,,,,,,''..''cxkO0Oxl:,,,,,,,,,,,,,,,,,,,,,,',,,,,,,,,,,,,,,'..,o0MMMMMMMM
// MMMMMMMM0,.....'',,,,,,,,,,,,,,,,,,,'.':xkOOd;'',,,,,,,,,,,,,,,,,,,,'''',,,,,,,,,,,,,'..'kWMMMMMMMMM
// MMMMMMMMW0;......'',,,,,,,,,,,,,,,,,,'';dkkd:,,,,,,,,,,,,,,,,,,,,,,'''',,,,,,,,,,,,,'..'xWMMMMMMMMMM
// MMMMMMMMMMKl.......'',,,,,,,,,,,,,,,,,,,cdl;,,,,,,,,,,,,,,,,,,,,'''''',,,,,,,,,,,,,'..'xNMMMMMMMMMMM
// MMMMMMMMMMMNx,.......''',,,,,,,,,,,,,,,',;,',,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,''...;OWMMMMMMMMMMMM
// MMMMMMMMMMMMNk;..........'',,,,,,,,,,,,,'..',,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,'....'oXMMMMMMMMMMMMMM
// MMMMMMMMMMMMMWXx;.......'',,,,,,,,,,,,,,'..',,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,'....'l0WMMMMMMMMMMMMMMM
// MMMMMMMMMMMMMMMMN0o;......''''''''',,,,,,''',,,,,,,,,,,,,,,,,,,,,''',,,,,''....'l0WMMMMMMMMMMMMMMMMM
// MMMMMMMMMMMMMMMMMMMNk:..............'''''','',,,,,,,,,,,,,,,,'''...''''...':ccdKWMMMMMMMMMMMMMMMMMMM
// MMMMMMMMMMMMMMMMMMMMMN0dc;'..................''''''''''''''..........';cokKNNNMMMMMMMMMMMMMMMMMMMMMM
// MMMMMMMMMMMMMMMMMMMMMMMMMNX0Okxddoolc::;,'............''','...',:loxOKNWMMMMMMMMMMMMMMMMMMMMMMMMMMMM
// MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMWWNXK0OOOkkkkkOOO0KKK000KXNWMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
// MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"AddressGreylisted","type":"error"},{"inputs":[],"name":"InitializeFailed","type":"error"},{"inputs":[],"name":"InvalidOwnershipAcceptance","type":"error"},{"inputs":[],"name":"NotOwnerOrTimelock","type":"error"},{"inputs":[],"name":"OnlyOwner","type":"error"},{"inputs":[],"name":"OwnerCannotBeZero","type":"error"},{"inputs":[],"name":"SenderNotRewarder","type":"error"},{"inputs":[],"name":"TransferHelperTransferFailed","type":"error"},{"inputs":[],"name":"YieldCollectionPaused","type":"error"},{"inputs":[],"name":"YieldPeriodMustCompleteBeforeChangingToNewPeriod","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"addr","type":"address"}],"name":"AddlVeFXSContractAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"addr","type":"address"}],"name":"AddlVeFXSContractRemoved","type":"event"},{"anonymous":false,"inputs":[],"name":"DefaultInitialization","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"oldOwner","type":"address"},{"indexed":false,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnerChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnerNominated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"RecoveredERC20","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"reward","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"yieldRate","type":"uint256"}],"name":"RewardAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"yield","type":"uint256"},{"indexed":false,"internalType":"address","name":"tokenAddress","type":"address"}],"name":"YieldCollected","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newDuration","type":"uint256"}],"name":"YieldDurationUpdated","type":"event"},{"inputs":[],"name":"acceptOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_addr","type":"address"}],"name":"addAddlVeFXSContract","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"addlVeContracts","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"addlVeContractsArr","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"allAddlVeContractsAddreses","outputs":[{"internalType":"address[]","name":"_addresses","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"allAddlVeContractsLength","outputs":[{"internalType":"uint256","name":"_length","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"checkpoint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"}],"name":"checkpointOtherUser","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"}],"name":"earned","outputs":[{"internalType":"uint256","name":"_earned","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"}],"name":"eligibleCurrentVeFXS","outputs":[{"internalType":"uint256","name":"_eligibleVefxsBal","type":"uint256"},{"internalType":"uint256","name":"_storedEndingTimestamp","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"emittedToken","outputs":[{"internalType":"contract ERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"emittedTokenAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"fpisLocker","outputs":[{"internalType":"contract IFPISLocker","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"fractionParticipating","outputs":[{"internalType":"uint256","name":"_fraction","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"}],"name":"getAllCurrActiveLocks","outputs":[{"components":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint128","name":"index","type":"uint128"},{"internalType":"int128","name":"amount","type":"int128"},{"internalType":"uint128","name":"end","type":"uint128"}],"internalType":"struct IveFXSStructs.LockedBalanceExtended[]","name":"_currActiveLocks","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getYield","outputs":[{"internalType":"uint256","name":"_yield0","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getYieldForDuration","outputs":[{"internalType":"uint256","name":"_yield","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"greylist","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_address","type":"address"}],"name":"greylistAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_owner","type":"address"},{"internalType":"address","name":"_timelockAddress","type":"address"},{"internalType":"address","name":"_emittedToken","type":"address"},{"internalType":"address[6]","name":"_veAddresses","type":"address[6]"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"l1VeFXSTotalSupplyOracle","outputs":[{"internalType":"contract L1VeFXSTotalSupplyOracle","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"l1veFXS","outputs":[{"internalType":"contract IL1VeFXS","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lFpisUtils","outputs":[{"internalType":"contract FPISLockerUtils","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lastTimeYieldApplicable","outputs":[{"internalType":"uint256","name":"_ts","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lastUpdateTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_owner","type":"address"}],"name":"nominateNewOwner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"nominatedOwner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"notifyRewardAmount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"periodFinish","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_tokenAddress","type":"address"},{"internalType":"uint256","name":"_tokenAmount","type":"uint256"}],"name":"recoverERC20","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_addr","type":"address"}],"name":"removeAddlVeFXSContract","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"rewardNotifiers","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[6]","name":"_veAddresses","type":"address[6]"}],"name":"setAddresses","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_yieldCollectionPaused","type":"bool"}],"name":"setPauses","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_newTimelock","type":"address"}],"name":"setTimelock","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_yieldDuration","type":"uint256"}],"name":"setYieldDuration","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_newRate","type":"uint256"},{"internalType":"bool","name":"_syncToo","type":"bool"}],"name":"setYieldRate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"sync","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"timelockAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_notifierAddr","type":"address"}],"name":"toggleRewardNotifier","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"totalComboVeFXSSupplyStored","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalVeFXSParticipating","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"}],"name":"ttlCombinedVeFXS","outputs":[{"internalType":"uint256","name":"_currBal","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ttlCombinedVeFXSTotalSupply","outputs":[{"internalType":"uint256","name":"_totalSupply","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"userIsInitialized","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"userVeFXSCheckpointed","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"userVeFXSEndpointCheckpointed","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"userYieldPerTokenPaid","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"veFXS","outputs":[{"internalType":"contract IVestedFXS","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"veFXSUtils","outputs":[{"internalType":"contract IVestedFXSUtils","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"yieldCollectionPaused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"yieldDuration","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"yieldPerVeFXS","outputs":[{"internalType":"uint256","name":"_yield","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"yieldPerVeFXSStored","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"yieldRate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"yields","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"}]Contract Creation Code
6080604052601d805460ff1916905534801561001a57600080fd5b50600080546001600160a01b0319163390811782556040805192835260208301919091527fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c910160405180910390a160016002556143208061007d6000396000f3fe608060405234801561001057600080fd5b50600436106103825760003560e01c8063819abfcd116101de578063c8f33c911161010f578063f0657ab6116100ad578063f868139b1161007c578063f868139b14610823578063fc939bb114610843578063fdda6ea31461084b578063fff6cae91461085e57600080fd5b8063f0657ab6146107db578063f21b7235146103c2578063f43ae1c7146107e3578063f5d812cb1461080357600080fd5b8063e172cf21116100e9578063e172cf2114610789578063e9218ff614610792578063ebe2b12b146107b2578063ee73e046146107bb57600080fd5b8063c8f33c911461074a578063d15166ff14610753578063d96658d91461077657600080fd5b80639f8a835a1161017c578063ad1148cb11610156578063ad1148cb1461071a578063bdacb30314610727578063c0f456bd1461073a578063c2c4c5c11461074257600080fd5b80639f8a835a146106de5780639faf3c6b146106f1578063a875f472146106fa57600080fd5b806391519bda116101b857806391519bda14610685578063941d9f6514610698578063948e25a2146106ab57806399bf7109146106be57600080fd5b8063819abfcd146106495780638980f11f146106525780638da5cb5b1461066557600080fd5b806350fe98ac116102b85780636869f42f1161025657806374ea0b981161023057806374ea0b98146106065780637873fae61461061957806379ba5097146106395780637c2628711461064157600080fd5b80636869f42f146105cd5780636999ac93146105d557806373f22f74146105de57600080fd5b806354e04d151161029257806354e04d151461058957806356d9fff314610592578063576221561461059a578063681b5ffa146105ad57600080fd5b806350fe98ac14610534578063525456d21461055457806353a47bb71461056957600080fd5b806319ff52fd116103255780633c6b16ab116102ff5780633c6b16ab146104ce57806342c92f6e146104e157806345ff83cb146104f45780634bc66f321461051457600080fd5b806319ff52fd146104685780632f9b12f81461048857806331ca208c146104ab57600080fd5b806314b305371161036157806314b30537146103d557806314b64f7c146104085780631627540c1461044d57806319aec6d21461046057600080fd5b80628cc2621461038757806303d8477f146103ad578063054d2d1e146103c2575b600080fd5b61039a610395366004613acf565b610866565b6040519081526020015b60405180910390f35b6103c06103bb366004613aec565b610b0b565b005b6103c06103d0366004613acf565b6111c6565b6103f86103e3366004613acf565b60186020526000908152604090205460ff1681565b60405190151581526020016103a4565b6008546104289073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016103a4565b6103c061045b366004613acf565b6112d0565b61039a611394565b6005546104289073ffffffffffffffffffffffffffffffffffffffff1681565b6103f8610496366004613acf565b600d6020526000908152604090205460ff1681565b6103f86104b9366004613acf565b601c6020526000908152604090205460ff1681565b6103c06104dc366004613b0e565b6113ab565b6103c06104ef366004613acf565b6114db565b61039a610502366004613acf565b60196020526000908152604090205481565b600b546104289073ffffffffffffffffffffffffffffffffffffffff1681565b61039a610542366004613acf565b60156020526000908152604090205481565b61055c6115a6565b6040516103a49190613b27565b6001546104289073ffffffffffffffffffffffffffffffffffffffff1681565b61039a60135481565b61039a611615565b6104286105a8366004613b0e565b61162c565b61039a6105bb366004613acf565b601a6020526000908152604090205481565b61039a611663565b61039a60105481565b6105f16105ec366004613acf565b6116c4565b604080519283526020830191909152016103a4565b6103c0610614366004613b0e565b611716565b6003546104289073ffffffffffffffffffffffffffffffffffffffff1681565b6103c061180c565b61039a611901565b61039a60165481565b6103c0610660366004613b81565b611ac1565b6000546104289073ffffffffffffffffffffffffffffffffffffffff1681565b6103c0610693366004613bbb565b611bb0565b6103c06106a6366004613acf565b611c3e565b6103c06106b9366004613beb565b611d09565b6106d16106cc366004613acf565b611db1565b6040516103a49190613c08565b6103c06106ec366004613acf565b612825565b61039a60175481565b61039a610708366004613acf565b60146020526000908152604090205481565b601d546103f89060ff1681565b6103c0610735366004613acf565b61282e565b600c5461039a565b6103c06128ec565b61039a600f5481565b6103f8610761366004613acf565b60126020526000908152604090205460ff1681565b61039a610784366004613acf565b6128f7565b61039a60115481565b6009546104289073ffffffffffffffffffffffffffffffffffffffff1681565b61039a600e5481565b6004546104289073ffffffffffffffffffffffffffffffffffffffff1681565b61039a612c2c565b600a546104289073ffffffffffffffffffffffffffffffffffffffff1681565b6006546104289073ffffffffffffffffffffffffffffffffffffffff1681565b6007546104289073ffffffffffffffffffffffffffffffffffffffff1681565b61039a613049565b6103c0610859366004613d2b565b613079565b6103c0613306565b73ffffffffffffffffffffffffffffffffffffffff811660009081526018602052604081205460ff1661089b57506000919050565b6000806108a7846116c4565b9092509050620f424060008390036109735773ffffffffffffffffffffffffffffffffffffffff85166000908152601b602052604090205482116108f057506000949350505050565b73ffffffffffffffffffffffffffffffffffffffff85166000908152601b60205260408120546109209084613dfd565b73ffffffffffffffffffffffffffffffffffffffff87166000908152601b6020526040812054919250906109549042613dfd565b90508061096483620f4240613e16565b61096e9190613e2d565b925050505b73ffffffffffffffffffffffffffffffffffffffff8516600090815260196020526040812054808511156109a957809150610a63565b60026109b58287613e68565b6109bf9190613e2d565b73ffffffffffffffffffffffffffffffffffffffff8816600090815260156020526040812054919350906109fe620f4240670de0b6b3a7640000613e16565b73ffffffffffffffffffffffffffffffffffffffff8a166000908152601460205260409020548690610a2e611663565b610a389190613dfd565b610a429086613e16565b610a4c9190613e16565b610a569190613e2d565b610a609190613e68565b50505b73ffffffffffffffffffffffffffffffffffffffff8716600090815260156020526040902054610a9e620f4240670de0b6b3a7640000613e16565b73ffffffffffffffffffffffffffffffffffffffff89166000908152601460205260409020548590610ace611663565b610ad89190613dfd565b610ae29086613e16565b610aec9190613e16565b610af69190613e2d565b610b009190613e68565b979650505050505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314801590610b4b5750600b5473ffffffffffffffffffffffffffffffffffffffff163314155b15610b82576040517ffee4291a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000610b916020830183613acf565b73ffffffffffffffffffffffffffffffffffffffff1603610c13576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f7665465853206d757374206e6f7420626520307830000000000000000000000060448201526064015b60405180910390fd5b6000610c256040830160208401613acf565b73ffffffffffffffffffffffffffffffffffffffff1603610ca2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601a60248201527f76654658535574696c73206d757374206e6f74206265203078300000000000006044820152606401610c0a565b6000610cb46060830160408401613acf565b73ffffffffffffffffffffffffffffffffffffffff1614610d31576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f43616e6e6f742061646420465049534c6f636b657220796574000000000000006044820152606401610c0a565b6000610d436080830160608401613acf565b73ffffffffffffffffffffffffffffffffffffffff1614610dc0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f43616e6e6f742061646420465049534c6f636b65725574696c732079657400006044820152606401610c0a565b6000610dd260a0830160808401613acf565b73ffffffffffffffffffffffffffffffffffffffff1614610e4f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f43616e6e6f7420616464204c31566546585320796574000000000000000000006044820152606401610c0a565b6000610e6160c0830160a08401613acf565b73ffffffffffffffffffffffffffffffffffffffff1614610f04576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f43616e6e6f7420616464204c315665465853546f74616c537570706c794f726160448201527f636c6520796574000000000000000000000000000000000000000000000000006064820152608401610c0a565b610f116020820182613acf565b600580547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055610f666040820160208301613acf565b600680547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff929092169190911790556000610fbd6060830160408401613acf565b73ffffffffffffffffffffffffffffffffffffffff161415801561100757506000610fee6080830160608401613acf565b73ffffffffffffffffffffffffffffffffffffffff1614155b156110b75761101c6060820160408301613acf565b600380547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff929092169190911790556110716080820160608301613acf565b600780547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff929092169190911790555b60006110c960a0830160808401613acf565b73ffffffffffffffffffffffffffffffffffffffff1614158015611113575060006110fa60c0830160a08401613acf565b73ffffffffffffffffffffffffffffffffffffffff1614155b156111c35761112860a0820160808301613acf565b600480547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905561117d60c0820160a08301613acf565b600880547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff929092169190911790555b50565b60005473ffffffffffffffffffffffffffffffffffffffff1633148015906112065750600b5473ffffffffffffffffffffffffffffffffffffffff163314155b1561123d576040517ffee4291a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f43616e6e6f74206164642f72656d6f7665206164646974696f6e616c2076654660448201527f585320736f7572636573207965740000000000000000000000000000000000006064820152608401610c0a565b60405180910390a150565b60005473ffffffffffffffffffffffffffffffffffffffff163314611321576040517f5fc483c500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040519081527f906a1c6bd7e3091ea86693dd029a831c19049ce77f1dce2ce0bab1cacbabce22906020016112c5565b60006011546010546113a69190613e16565b905090565b3360009081526012602052604090205460ff166113f4576040517fae582d4300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6009546114199073ffffffffffffffffffffffffffffffffffffffff16333084613329565b611421613306565b600e54421061143f576011546114379082613e2d565b601055611481565b600042600e5461144f9190613dfd565b90506000601054826114619190613e16565b6011549091506114718285613e68565b61147b9190613e2d565b60105550505b42600f81905560115461149391613e68565b600e5561149e612c2c565b6017556010546040805183815260208101929092527f6c07ee05dcf262f13abf9d87b846ee789d2f90fe991d495acd7d7fc109ee1f5591016112c5565b60005473ffffffffffffffffffffffffffffffffffffffff16331480159061151b5750600b5473ffffffffffffffffffffffffffffffffffffffff163314155b15611552576040517ffee4291a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff16600090815260126020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00811660ff90911615179055565b6060600c80548060200260200160405190810160405280929190818152602001828054801561160b57602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff1681526001909101906020018083116115e0575b5050505050905090565b6000600e5442106116275750600e5490565b504290565b600c818154811061163c57600080fd5b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff16905081565b6000601754600003611676575060135490565b601754601054600f54611687611615565b6116919190613dfd565b61169b9190613e16565b6116ad90670de0b6b3a7640000613e16565b6116b79190613e2d565b6013546113a69190613e68565b60008060006116d2846128f7565b73ffffffffffffffffffffffffffffffffffffffff85166000908152601a60205260409020549250905042821161170c5760009250611710565b8092505b50915091565b60005473ffffffffffffffffffffffffffffffffffffffff1633148015906117565750600b5473ffffffffffffffffffffffffffffffffffffffff163314155b1561178d576040517ffee4291a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600e54158015906117a05750600e544211155b156117d7576040517f350e95f600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60118190556040518181527fce653f06b9044b00e7d9d01b9b4228e84812092cb6a38371889bef19370d21f7906020016112c5565b60015473ffffffffffffffffffffffffffffffffffffffff16331461185d576040517fd74b334e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000546001546040805173ffffffffffffffffffffffffffffffffffffffff93841681529290911660208301527fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c910160405180910390a160018054600080547fffffffffffffffffffffffff000000000000000000000000000000000000000090811673ffffffffffffffffffffffffffffffffffffffff841617909155169055565b6000600280540361196e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610c0a565b60028055601d5460ff16156119af576040517f6efa33c900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b336119b9816133c4565b336000908152601c602052604090205460ff1615611a03576040517f70e5228400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3360009081526015602052604090205491508115611aa65733600081815260156020526040812055600a54611a519173ffffffffffffffffffffffffffffffffffffffff9091169084613609565b600a546040805184815273ffffffffffffffffffffffffffffffffffffffff909216602083015233917f3998039806f6db7e5d83a5371638cc47dd2e9ae500d5d561d95ec6381f53e3cd910160405180910390a25b50336000908152601b60205260409020429055600160025590565b60005473ffffffffffffffffffffffffffffffffffffffff163314801590611b015750600b5473ffffffffffffffffffffffffffffffffffffffff163314155b15611b38576040517ffee4291a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600054611b5d90839073ffffffffffffffffffffffffffffffffffffffff1683613609565b6040805173ffffffffffffffffffffffffffffffffffffffff84168152602081018390527f55350610fe57096d8c0ffa30beede987326bccfcb0b4415804164d0dd50ce8b1910160405180910390a15050565b60005473ffffffffffffffffffffffffffffffffffffffff163314801590611bf05750600b5473ffffffffffffffffffffffffffffffffffffffff163314155b15611c27576040517ffee4291a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60108290558015611c3a57611c3a613306565b5050565b60005473ffffffffffffffffffffffffffffffffffffffff163314801590611c7e5750600b5473ffffffffffffffffffffffffffffffffffffffff163314155b15611cb5576040517ffee4291a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff166000908152601c6020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00811660ff90911615179055565b60005473ffffffffffffffffffffffffffffffffffffffff163314801590611d495750600b5473ffffffffffffffffffffffffffffffffffffffff163314155b15611d80576040517ffee4291a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b601d80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016911515919091179055565b6005546040517fb9ef083000000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff838116600483015260609260009291169063b9ef083090602401602060405180830381865afa158015611e26573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e4a9190614165565b6003546fffffffffffffffffffffffffffffffff91909116915073ffffffffffffffffffffffffffffffffffffffff1615611f32576003546040517fb9ef083000000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff85811660048301529091169063b9ef083090602401602060405180830381865afa158015611eef573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f139190614165565b611f2f906fffffffffffffffffffffffffffffffff1682613e68565b90505b60045473ffffffffffffffffffffffffffffffffffffffff1615801590611f70575060085473ffffffffffffffffffffffffffffffffffffffff1615155b15611f8357611f80600182613e68565b90505b60005b600c54811015612087576000600c8281548110611fa557611fa5613e7b565b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff169050801561207e576040517fb9ef083000000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff868116600483015282169063b9ef083090602401602060405180830381865afa15801561203b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061205f9190614165565b61207b906fffffffffffffffffffffffffffffffff1684613e68565b92505b50600101611f86565b506000808267ffffffffffffffff8111156120a4576120a4613c84565b60405190808252806020026020018201604052801561211457816020015b6040805160808101825260008082526020808301829052928201819052606082015282527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9092019101816120c25790505b506006546040517f3c59331200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff888116600483015292935060009290911690633c59331290602401600060405180830381865afa15801561218b573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526121d19190810190614082565b60600151905060005b81518110156122345760008282815181106121f7576121f7613e7b565b602002602001015190508084868151811061221457612214613e7b565b60200260200101819052508461222990614180565b9450506001016121da565b505060035473ffffffffffffffffffffffffffffffffffffffff16156123e7576007546040517f3c59331200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff87811660048301526000921690633c59331290602401600060405180830381865afa1580156122c5573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016820160405261230b9190810190614082565b60600151905060005b81518110156123e457600082828151811061233157612331613e7b565b602002602001015190504281606001516fffffffffffffffffffffffffffffffff1611156123db5760405180608001604052808260000151815260200182602001516fffffffffffffffffffffffffffffffff1681526020018260400151600f0b815260200182606001516fffffffffffffffffffffffffffffffff168152508486815181106123c3576123c3613e7b565b6020026020010181905250846123d890614180565b94505b50600101612314565b50505b60045473ffffffffffffffffffffffffffffffffffffffff1615801590612425575060085473ffffffffffffffffffffffffffffffffffffffff1615155b1561256457600480546040517fcbf9fe5f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff888116938201939093526000929091169063cbf9fe5f90602401606060405180830381865afa1580156124a0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124c491906141d0565b905042816020015167ffffffffffffffff1611156125625760405180608001604052806000815260200160006fffffffffffffffffffffffffffffffff1681526020018260000151600f0b8152602001826020015167ffffffffffffffff166fffffffffffffffffffffffffffffffff1681525082848151811061254a5761254a613e7b565b60200260200101819052508261255f90614180565b92505b505b60005b600c54811015612744576000600c828154811061258657612586613e7b565b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff169050801561273b5760008173ffffffffffffffffffffffffffffffffffffffff166366d6bff96040518163ffffffff1660e01b8152600401602060405180830381865afa1580156125fd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126219190613ed3565b6040517f3c59331200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8a811660048301529190911690633c59331290602401600060405180830381865afa15801561268f573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526126d59190810190614082565b60600151905060005b81518110156127385760008282815181106126fb576126fb613e7b565b602002602001015190508086888151811061271857612718613e7b565b60200260200101819052508661272d90614180565b9650506001016126de565b50505b50600101612567565b508167ffffffffffffffff81111561275e5761275e613c84565b6040519080825280602002602001820160405280156127ce57816020015b6040805160808101825260008082526020808301829052928201819052606082015282527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90920191018161277c5790505b50935060005b845181101561281c578181815181106127ef576127ef613e7b565b602002602001015185828151811061280957612809613e7b565b60209081029190910101526001016127d4565b50505050919050565b6111c3816133c4565b60005473ffffffffffffffffffffffffffffffffffffffff16331480159061286e5750600b5473ffffffffffffffffffffffffffffffffffffffff163314155b156128a5576040517ffee4291a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600b80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b6128f5336133c4565b565b6005546040517f70a0823100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff838116600483015260009216906370a0823190602401602060405180830381865afa158015612968573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061298c9190613eaa565b60035490915073ffffffffffffffffffffffffffffffffffffffff1615612a4e576003546040517f70a0823100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8481166004830152909116906370a0823190602401602060405180830381865afa158015612a1d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a419190613eaa565b612a4b9082613e68565b90505b60045473ffffffffffffffffffffffffffffffffffffffff1615801590612a8c575060085473ffffffffffffffffffffffffffffffffffffffff1615155b15612b3457600480546040517f70a0823100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff858116938201939093529116906370a0823190602401602060405180830381865afa158015612b03573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b279190613eaa565b612b319082613e68565b90505b60005b600c54811015612c26576000600c8281548110612b5657612b56613e7b565b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff1690508015612c1d576040517f70a0823100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff85811660048301528216906370a0823190602401602060405180830381865afa158015612bec573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c109190613eaa565b612c1a9084613e68565b92505b50600101612b37565b50919050565b600554604080517f18160ddd000000000000000000000000000000000000000000000000000000008152905160009273ffffffffffffffffffffffffffffffffffffffff16916318160ddd9160048083019260209291908290030181865afa158015612c9c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612cc09190613eaa565b60035490915073ffffffffffffffffffffffffffffffffffffffff1615612d7f57600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612d4e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d729190613eaa565b612d7c9082613e68565b90505b60045473ffffffffffffffffffffffffffffffffffffffff1615801590612dbd575060085473ffffffffffffffffffffffffffffffffffffffff1615155b15612e6057600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612e2f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612e539190613eaa565b612e5d9082613e68565b90505b60005b600c54811015612f31576000600c8281548110612e8257612e82613e7b565b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff1690508015612f28578073ffffffffffffffffffffffffffffffffffffffff166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612ef7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f1b9190613eaa565b612f259084613e68565b92505b50600101612e63565b5090565b600c54811015612ffa578173ffffffffffffffffffffffffffffffffffffffff16600c8281548110612f6957612f69613e7b565b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff1603612ff2576000600c8281548110612fa557612fa5613e7b565b9060005260206000200160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550612ffa565b600101612f35565b50613003613306565b60405173ffffffffffffffffffffffffffffffffffffffff821681527ff3517f912cde760e82811897047177df419c7aa16326d5710e6b425a8a7d1035906020016112c5565b600060175460000361305b5750600090565b601754620f424060165461306f9190613e16565b6113a69190613e2d565b73ffffffffffffffffffffffffffffffffffffffff821615806130b35750600a5473ffffffffffffffffffffffffffffffffffffffff1615155b156130ea576040517fd08e7ac200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000805473ffffffffffffffffffffffffffffffffffffffff8681167fffffffffffffffffffffffff000000000000000000000000000000000000000092831617909255600a805485841690831681179091556009805483169091179055600b80548684169083161790558251600580548316918416919091179055602083015160068054909216908316179055604082015116158015906131a55750606081015173ffffffffffffffffffffffffffffffffffffffff1615155b156132065760408101516003805473ffffffffffffffffffffffffffffffffffffffff9283167fffffffffffffffffffffffff0000000000000000000000000000000000000000918216179091556060830151600780549190931691161790555b608081015173ffffffffffffffffffffffffffffffffffffffff1615801590613248575060a081015173ffffffffffffffffffffffffffffffffffffffff1615155b156132a95760808101516004805473ffffffffffffffffffffffffffffffffffffffff9283167fffffffffffffffffffffffff00000000000000000000000000000000000000009182161790915560a0830151600880549190931691161790555b505042600f555073ffffffffffffffffffffffffffffffffffffffff16600090815260126020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905562093a80601155565b61330e611663565b601355613319612c2c565b601755613324611615565b600f55565b6040805173ffffffffffffffffffffffffffffffffffffffff85811660248301528416604482015260648082018490528251808303909101815260849091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f23b872dd000000000000000000000000000000000000000000000000000000001790526133be908590613747565b50505050565b6133cc613306565b6133d581613858565b73ffffffffffffffffffffffffffffffffffffffff811660009081526019602052604081205490613405836128f7565b73ffffffffffffffffffffffffffffffffffffffff8416600090815260196020526040812082905590915061343984611db1565b905060008082511115613468578160008151811061345957613459613e7b565b60200260200101516060015190505b6001825111156134f25760005b82518110156134f057816fffffffffffffffffffffffffffffffff168382815181106134a3576134a3613e7b565b6020026020010151606001516fffffffffffffffffffffffffffffffff1610156134e8578281815181106134d9576134d9613e7b565b60200260200101516060015191505b600101613475565b505b73ffffffffffffffffffffffffffffffffffffffff85166000908152601a602052604090206fffffffffffffffffffffffffffffffff8216905583831061355857600061353f8585613dfd565b90508060165461354f9190613e68565b60165550613579565b60006135648486613dfd565b9050806016546135749190613dfd565b601655505b73ffffffffffffffffffffffffffffffffffffffff851660009081526018602052604090205460ff166136025773ffffffffffffffffffffffffffffffffffffffff8516600090815260186020908152604080832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055601b90915290204290555b5050505050565b6040805173ffffffffffffffffffffffffffffffffffffffff8481166024830152604480830185905283518084039091018152606490920183526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb0000000000000000000000000000000000000000000000000000000017905291516000928392908716916136a09190614260565b6000604051808303816000865af19150503d80600081146136dd576040519150601f19603f3d011682016040523d82523d6000602084013e6136e2565b606091505b5091509150811580613710575080511580159061371057508080602001905181019061370e919061427c565b155b15613602576040517f19a9708500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006137a9826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166138bb9092919063ffffffff16565b80519091501561385357808060200190518101906137c7919061427c565b613853576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610c0a565b505050565b73ffffffffffffffffffffffffffffffffffffffff8116156111c357600061387f82610866565b73ffffffffffffffffffffffffffffffffffffffff83166000908152601560209081526040808320939093556013546014909152919020555050565b60606138ca84846000856138d4565b90505b9392505050565b606082471015613966576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610c0a565b73ffffffffffffffffffffffffffffffffffffffff85163b6139e4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610c0a565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051613a0d9190614260565b60006040518083038185875af1925050503d8060008114613a4a576040519150601f19603f3d011682016040523d82523d6000602084013e613a4f565b606091505b5091509150610b0082828660608315613a695750816138cd565b825115613a795782518084602001fd5b816040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c0a9190614299565b73ffffffffffffffffffffffffffffffffffffffff811681146111c357600080fd5b600060208284031215613ae157600080fd5b81356138cd81613aad565b600060c08284031215613afe57600080fd5b8260c083011115612c2657600080fd5b600060208284031215613b2057600080fd5b5035919050565b6020808252825182820181905260009190848201906040850190845b81811015613b7557835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101613b43565b50909695505050505050565b60008060408385031215613b9457600080fd5b8235613b9f81613aad565b946020939093013593505050565b80151581146111c357600080fd5b60008060408385031215613bce57600080fd5b823591506020830135613be081613bad565b809150509250929050565b600060208284031215613bfd57600080fd5b81356138cd81613bad565b602080825282518282018190526000919060409081850190868401855b82811015613c7757815180518552868101516fffffffffffffffffffffffffffffffff9081168887015286820151600f0b87870152606091820151169085015260809093019290850190600101613c25565b5091979650505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60405160c0810167ffffffffffffffff81118282101715613cd657613cd6613c84565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715613d2357613d23613c84565b604052919050565b600080600080610120808688031215613d4357600080fd5b8535613d4e81613aad565b9450602086810135613d5f81613aad565b94506040870135613d6f81613aad565b9350607f87018813613d8057600080fd5b613d88613cb3565b918701918089841115613d9a57600080fd5b606089015b84811015613dbf578035613db281613aad565b8352918301918301613d9f565b50969995985093965050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b81810381811115613e1057613e10613dce565b92915050565b8082028115828204841417613e1057613e10613dce565b600082613e63577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b80820180821115613e1057613e10613dce565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600060208284031215613ebc57600080fd5b5051919050565b8051613ece81613aad565b919050565b600060208284031215613ee557600080fd5b81516138cd81613aad565b80516fffffffffffffffffffffffffffffffff81168114613ece57600080fd5b8051600f81900b8114613ece57600080fd5b600082601f830112613f3357600080fd5b8151602067ffffffffffffffff80831115613f5057613f50613c84565b613f5e828460051b01613cdc565b83815260079390931b85018201928281019087851115613f7d57600080fd5b8387015b8581101561400157608080828b031215613f9b5760008081fd5b60408051918201918683118184101715613fb757613fb7613c84565b82825283518152613fc9888501613ef0565b88820152613fd8828501613f10565b8282015260609250613feb838501613ef0565b9281019290925250835291840191608001613f81565b50979650505050505050565b600082601f83011261401e57600080fd5b6040516060810181811067ffffffffffffffff8211171561404157614041613c84565b60405280606084018581111561405657600080fd5b845b818110156140775761406981613f10565b835260209283019201614058565b509195945050505050565b60006020828403121561409457600080fd5b815167ffffffffffffffff808211156140ac57600080fd5b9083019061010082860312156140c157600080fd5b6140c9613cb3565b6140d283613ec3565b8152602083015160208201526040830151828111156140f057600080fd5b6140fc87828601613f22565b60408301525060608301518281111561411457600080fd5b61412087828601613f22565b60608301525060808301518281111561413857600080fd5b61414487828601613f22565b6080830152506141578660a0850161400d565b60a082015295945050505050565b60006020828403121561417757600080fd5b6138cd82613ef0565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036141b1576141b1613dce565b5060010190565b805167ffffffffffffffff81168114613ece57600080fd5b6000606082840312156141e257600080fd5b6040516060810181811067ffffffffffffffff8211171561420557614205613c84565b60405261421183613ef0565b815261421f602084016141b8565b6020820152614230604084016141b8565b60408201529392505050565b60005b8381101561425757818101518382015260200161423f565b50506000910152565b6000825161427281846020870161423c565b9190910192915050565b60006020828403121561428e57600080fd5b81516138cd81613bad565b60208152600082518060208401526142b881604085016020870161423c565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea2646970667358221220bdc4a560a633ac5b2164af384022d2f11c5e07eac8e8d767d5283a718ff7dd4364736f6c63430008170033
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106103825760003560e01c8063819abfcd116101de578063c8f33c911161010f578063f0657ab6116100ad578063f868139b1161007c578063f868139b14610823578063fc939bb114610843578063fdda6ea31461084b578063fff6cae91461085e57600080fd5b8063f0657ab6146107db578063f21b7235146103c2578063f43ae1c7146107e3578063f5d812cb1461080357600080fd5b8063e172cf21116100e9578063e172cf2114610789578063e9218ff614610792578063ebe2b12b146107b2578063ee73e046146107bb57600080fd5b8063c8f33c911461074a578063d15166ff14610753578063d96658d91461077657600080fd5b80639f8a835a1161017c578063ad1148cb11610156578063ad1148cb1461071a578063bdacb30314610727578063c0f456bd1461073a578063c2c4c5c11461074257600080fd5b80639f8a835a146106de5780639faf3c6b146106f1578063a875f472146106fa57600080fd5b806391519bda116101b857806391519bda14610685578063941d9f6514610698578063948e25a2146106ab57806399bf7109146106be57600080fd5b8063819abfcd146106495780638980f11f146106525780638da5cb5b1461066557600080fd5b806350fe98ac116102b85780636869f42f1161025657806374ea0b981161023057806374ea0b98146106065780637873fae61461061957806379ba5097146106395780637c2628711461064157600080fd5b80636869f42f146105cd5780636999ac93146105d557806373f22f74146105de57600080fd5b806354e04d151161029257806354e04d151461058957806356d9fff314610592578063576221561461059a578063681b5ffa146105ad57600080fd5b806350fe98ac14610534578063525456d21461055457806353a47bb71461056957600080fd5b806319ff52fd116103255780633c6b16ab116102ff5780633c6b16ab146104ce57806342c92f6e146104e157806345ff83cb146104f45780634bc66f321461051457600080fd5b806319ff52fd146104685780632f9b12f81461048857806331ca208c146104ab57600080fd5b806314b305371161036157806314b30537146103d557806314b64f7c146104085780631627540c1461044d57806319aec6d21461046057600080fd5b80628cc2621461038757806303d8477f146103ad578063054d2d1e146103c2575b600080fd5b61039a610395366004613acf565b610866565b6040519081526020015b60405180910390f35b6103c06103bb366004613aec565b610b0b565b005b6103c06103d0366004613acf565b6111c6565b6103f86103e3366004613acf565b60186020526000908152604090205460ff1681565b60405190151581526020016103a4565b6008546104289073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016103a4565b6103c061045b366004613acf565b6112d0565b61039a611394565b6005546104289073ffffffffffffffffffffffffffffffffffffffff1681565b6103f8610496366004613acf565b600d6020526000908152604090205460ff1681565b6103f86104b9366004613acf565b601c6020526000908152604090205460ff1681565b6103c06104dc366004613b0e565b6113ab565b6103c06104ef366004613acf565b6114db565b61039a610502366004613acf565b60196020526000908152604090205481565b600b546104289073ffffffffffffffffffffffffffffffffffffffff1681565b61039a610542366004613acf565b60156020526000908152604090205481565b61055c6115a6565b6040516103a49190613b27565b6001546104289073ffffffffffffffffffffffffffffffffffffffff1681565b61039a60135481565b61039a611615565b6104286105a8366004613b0e565b61162c565b61039a6105bb366004613acf565b601a6020526000908152604090205481565b61039a611663565b61039a60105481565b6105f16105ec366004613acf565b6116c4565b604080519283526020830191909152016103a4565b6103c0610614366004613b0e565b611716565b6003546104289073ffffffffffffffffffffffffffffffffffffffff1681565b6103c061180c565b61039a611901565b61039a60165481565b6103c0610660366004613b81565b611ac1565b6000546104289073ffffffffffffffffffffffffffffffffffffffff1681565b6103c0610693366004613bbb565b611bb0565b6103c06106a6366004613acf565b611c3e565b6103c06106b9366004613beb565b611d09565b6106d16106cc366004613acf565b611db1565b6040516103a49190613c08565b6103c06106ec366004613acf565b612825565b61039a60175481565b61039a610708366004613acf565b60146020526000908152604090205481565b601d546103f89060ff1681565b6103c0610735366004613acf565b61282e565b600c5461039a565b6103c06128ec565b61039a600f5481565b6103f8610761366004613acf565b60126020526000908152604090205460ff1681565b61039a610784366004613acf565b6128f7565b61039a60115481565b6009546104289073ffffffffffffffffffffffffffffffffffffffff1681565b61039a600e5481565b6004546104289073ffffffffffffffffffffffffffffffffffffffff1681565b61039a612c2c565b600a546104289073ffffffffffffffffffffffffffffffffffffffff1681565b6006546104289073ffffffffffffffffffffffffffffffffffffffff1681565b6007546104289073ffffffffffffffffffffffffffffffffffffffff1681565b61039a613049565b6103c0610859366004613d2b565b613079565b6103c0613306565b73ffffffffffffffffffffffffffffffffffffffff811660009081526018602052604081205460ff1661089b57506000919050565b6000806108a7846116c4565b9092509050620f424060008390036109735773ffffffffffffffffffffffffffffffffffffffff85166000908152601b602052604090205482116108f057506000949350505050565b73ffffffffffffffffffffffffffffffffffffffff85166000908152601b60205260408120546109209084613dfd565b73ffffffffffffffffffffffffffffffffffffffff87166000908152601b6020526040812054919250906109549042613dfd565b90508061096483620f4240613e16565b61096e9190613e2d565b925050505b73ffffffffffffffffffffffffffffffffffffffff8516600090815260196020526040812054808511156109a957809150610a63565b60026109b58287613e68565b6109bf9190613e2d565b73ffffffffffffffffffffffffffffffffffffffff8816600090815260156020526040812054919350906109fe620f4240670de0b6b3a7640000613e16565b73ffffffffffffffffffffffffffffffffffffffff8a166000908152601460205260409020548690610a2e611663565b610a389190613dfd565b610a429086613e16565b610a4c9190613e16565b610a569190613e2d565b610a609190613e68565b50505b73ffffffffffffffffffffffffffffffffffffffff8716600090815260156020526040902054610a9e620f4240670de0b6b3a7640000613e16565b73ffffffffffffffffffffffffffffffffffffffff89166000908152601460205260409020548590610ace611663565b610ad89190613dfd565b610ae29086613e16565b610aec9190613e16565b610af69190613e2d565b610b009190613e68565b979650505050505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314801590610b4b5750600b5473ffffffffffffffffffffffffffffffffffffffff163314155b15610b82576040517ffee4291a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000610b916020830183613acf565b73ffffffffffffffffffffffffffffffffffffffff1603610c13576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f7665465853206d757374206e6f7420626520307830000000000000000000000060448201526064015b60405180910390fd5b6000610c256040830160208401613acf565b73ffffffffffffffffffffffffffffffffffffffff1603610ca2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601a60248201527f76654658535574696c73206d757374206e6f74206265203078300000000000006044820152606401610c0a565b6000610cb46060830160408401613acf565b73ffffffffffffffffffffffffffffffffffffffff1614610d31576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f43616e6e6f742061646420465049534c6f636b657220796574000000000000006044820152606401610c0a565b6000610d436080830160608401613acf565b73ffffffffffffffffffffffffffffffffffffffff1614610dc0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f43616e6e6f742061646420465049534c6f636b65725574696c732079657400006044820152606401610c0a565b6000610dd260a0830160808401613acf565b73ffffffffffffffffffffffffffffffffffffffff1614610e4f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f43616e6e6f7420616464204c31566546585320796574000000000000000000006044820152606401610c0a565b6000610e6160c0830160a08401613acf565b73ffffffffffffffffffffffffffffffffffffffff1614610f04576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f43616e6e6f7420616464204c315665465853546f74616c537570706c794f726160448201527f636c6520796574000000000000000000000000000000000000000000000000006064820152608401610c0a565b610f116020820182613acf565b600580547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055610f666040820160208301613acf565b600680547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff929092169190911790556000610fbd6060830160408401613acf565b73ffffffffffffffffffffffffffffffffffffffff161415801561100757506000610fee6080830160608401613acf565b73ffffffffffffffffffffffffffffffffffffffff1614155b156110b75761101c6060820160408301613acf565b600380547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff929092169190911790556110716080820160608301613acf565b600780547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff929092169190911790555b60006110c960a0830160808401613acf565b73ffffffffffffffffffffffffffffffffffffffff1614158015611113575060006110fa60c0830160a08401613acf565b73ffffffffffffffffffffffffffffffffffffffff1614155b156111c35761112860a0820160808301613acf565b600480547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905561117d60c0820160a08301613acf565b600880547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff929092169190911790555b50565b60005473ffffffffffffffffffffffffffffffffffffffff1633148015906112065750600b5473ffffffffffffffffffffffffffffffffffffffff163314155b1561123d576040517ffee4291a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f43616e6e6f74206164642f72656d6f7665206164646974696f6e616c2076654660448201527f585320736f7572636573207965740000000000000000000000000000000000006064820152608401610c0a565b60405180910390a150565b60005473ffffffffffffffffffffffffffffffffffffffff163314611321576040517f5fc483c500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040519081527f906a1c6bd7e3091ea86693dd029a831c19049ce77f1dce2ce0bab1cacbabce22906020016112c5565b60006011546010546113a69190613e16565b905090565b3360009081526012602052604090205460ff166113f4576040517fae582d4300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6009546114199073ffffffffffffffffffffffffffffffffffffffff16333084613329565b611421613306565b600e54421061143f576011546114379082613e2d565b601055611481565b600042600e5461144f9190613dfd565b90506000601054826114619190613e16565b6011549091506114718285613e68565b61147b9190613e2d565b60105550505b42600f81905560115461149391613e68565b600e5561149e612c2c565b6017556010546040805183815260208101929092527f6c07ee05dcf262f13abf9d87b846ee789d2f90fe991d495acd7d7fc109ee1f5591016112c5565b60005473ffffffffffffffffffffffffffffffffffffffff16331480159061151b5750600b5473ffffffffffffffffffffffffffffffffffffffff163314155b15611552576040517ffee4291a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff16600090815260126020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00811660ff90911615179055565b6060600c80548060200260200160405190810160405280929190818152602001828054801561160b57602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff1681526001909101906020018083116115e0575b5050505050905090565b6000600e5442106116275750600e5490565b504290565b600c818154811061163c57600080fd5b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff16905081565b6000601754600003611676575060135490565b601754601054600f54611687611615565b6116919190613dfd565b61169b9190613e16565b6116ad90670de0b6b3a7640000613e16565b6116b79190613e2d565b6013546113a69190613e68565b60008060006116d2846128f7565b73ffffffffffffffffffffffffffffffffffffffff85166000908152601a60205260409020549250905042821161170c5760009250611710565b8092505b50915091565b60005473ffffffffffffffffffffffffffffffffffffffff1633148015906117565750600b5473ffffffffffffffffffffffffffffffffffffffff163314155b1561178d576040517ffee4291a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600e54158015906117a05750600e544211155b156117d7576040517f350e95f600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60118190556040518181527fce653f06b9044b00e7d9d01b9b4228e84812092cb6a38371889bef19370d21f7906020016112c5565b60015473ffffffffffffffffffffffffffffffffffffffff16331461185d576040517fd74b334e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000546001546040805173ffffffffffffffffffffffffffffffffffffffff93841681529290911660208301527fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c910160405180910390a160018054600080547fffffffffffffffffffffffff000000000000000000000000000000000000000090811673ffffffffffffffffffffffffffffffffffffffff841617909155169055565b6000600280540361196e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610c0a565b60028055601d5460ff16156119af576040517f6efa33c900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b336119b9816133c4565b336000908152601c602052604090205460ff1615611a03576040517f70e5228400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3360009081526015602052604090205491508115611aa65733600081815260156020526040812055600a54611a519173ffffffffffffffffffffffffffffffffffffffff9091169084613609565b600a546040805184815273ffffffffffffffffffffffffffffffffffffffff909216602083015233917f3998039806f6db7e5d83a5371638cc47dd2e9ae500d5d561d95ec6381f53e3cd910160405180910390a25b50336000908152601b60205260409020429055600160025590565b60005473ffffffffffffffffffffffffffffffffffffffff163314801590611b015750600b5473ffffffffffffffffffffffffffffffffffffffff163314155b15611b38576040517ffee4291a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600054611b5d90839073ffffffffffffffffffffffffffffffffffffffff1683613609565b6040805173ffffffffffffffffffffffffffffffffffffffff84168152602081018390527f55350610fe57096d8c0ffa30beede987326bccfcb0b4415804164d0dd50ce8b1910160405180910390a15050565b60005473ffffffffffffffffffffffffffffffffffffffff163314801590611bf05750600b5473ffffffffffffffffffffffffffffffffffffffff163314155b15611c27576040517ffee4291a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60108290558015611c3a57611c3a613306565b5050565b60005473ffffffffffffffffffffffffffffffffffffffff163314801590611c7e5750600b5473ffffffffffffffffffffffffffffffffffffffff163314155b15611cb5576040517ffee4291a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff166000908152601c6020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00811660ff90911615179055565b60005473ffffffffffffffffffffffffffffffffffffffff163314801590611d495750600b5473ffffffffffffffffffffffffffffffffffffffff163314155b15611d80576040517ffee4291a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b601d80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016911515919091179055565b6005546040517fb9ef083000000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff838116600483015260609260009291169063b9ef083090602401602060405180830381865afa158015611e26573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e4a9190614165565b6003546fffffffffffffffffffffffffffffffff91909116915073ffffffffffffffffffffffffffffffffffffffff1615611f32576003546040517fb9ef083000000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff85811660048301529091169063b9ef083090602401602060405180830381865afa158015611eef573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f139190614165565b611f2f906fffffffffffffffffffffffffffffffff1682613e68565b90505b60045473ffffffffffffffffffffffffffffffffffffffff1615801590611f70575060085473ffffffffffffffffffffffffffffffffffffffff1615155b15611f8357611f80600182613e68565b90505b60005b600c54811015612087576000600c8281548110611fa557611fa5613e7b565b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff169050801561207e576040517fb9ef083000000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff868116600483015282169063b9ef083090602401602060405180830381865afa15801561203b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061205f9190614165565b61207b906fffffffffffffffffffffffffffffffff1684613e68565b92505b50600101611f86565b506000808267ffffffffffffffff8111156120a4576120a4613c84565b60405190808252806020026020018201604052801561211457816020015b6040805160808101825260008082526020808301829052928201819052606082015282527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9092019101816120c25790505b506006546040517f3c59331200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff888116600483015292935060009290911690633c59331290602401600060405180830381865afa15801561218b573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526121d19190810190614082565b60600151905060005b81518110156122345760008282815181106121f7576121f7613e7b565b602002602001015190508084868151811061221457612214613e7b565b60200260200101819052508461222990614180565b9450506001016121da565b505060035473ffffffffffffffffffffffffffffffffffffffff16156123e7576007546040517f3c59331200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff87811660048301526000921690633c59331290602401600060405180830381865afa1580156122c5573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016820160405261230b9190810190614082565b60600151905060005b81518110156123e457600082828151811061233157612331613e7b565b602002602001015190504281606001516fffffffffffffffffffffffffffffffff1611156123db5760405180608001604052808260000151815260200182602001516fffffffffffffffffffffffffffffffff1681526020018260400151600f0b815260200182606001516fffffffffffffffffffffffffffffffff168152508486815181106123c3576123c3613e7b565b6020026020010181905250846123d890614180565b94505b50600101612314565b50505b60045473ffffffffffffffffffffffffffffffffffffffff1615801590612425575060085473ffffffffffffffffffffffffffffffffffffffff1615155b1561256457600480546040517fcbf9fe5f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff888116938201939093526000929091169063cbf9fe5f90602401606060405180830381865afa1580156124a0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124c491906141d0565b905042816020015167ffffffffffffffff1611156125625760405180608001604052806000815260200160006fffffffffffffffffffffffffffffffff1681526020018260000151600f0b8152602001826020015167ffffffffffffffff166fffffffffffffffffffffffffffffffff1681525082848151811061254a5761254a613e7b565b60200260200101819052508261255f90614180565b92505b505b60005b600c54811015612744576000600c828154811061258657612586613e7b565b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff169050801561273b5760008173ffffffffffffffffffffffffffffffffffffffff166366d6bff96040518163ffffffff1660e01b8152600401602060405180830381865afa1580156125fd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126219190613ed3565b6040517f3c59331200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8a811660048301529190911690633c59331290602401600060405180830381865afa15801561268f573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526126d59190810190614082565b60600151905060005b81518110156127385760008282815181106126fb576126fb613e7b565b602002602001015190508086888151811061271857612718613e7b565b60200260200101819052508661272d90614180565b9650506001016126de565b50505b50600101612567565b508167ffffffffffffffff81111561275e5761275e613c84565b6040519080825280602002602001820160405280156127ce57816020015b6040805160808101825260008082526020808301829052928201819052606082015282527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90920191018161277c5790505b50935060005b845181101561281c578181815181106127ef576127ef613e7b565b602002602001015185828151811061280957612809613e7b565b60209081029190910101526001016127d4565b50505050919050565b6111c3816133c4565b60005473ffffffffffffffffffffffffffffffffffffffff16331480159061286e5750600b5473ffffffffffffffffffffffffffffffffffffffff163314155b156128a5576040517ffee4291a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600b80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b6128f5336133c4565b565b6005546040517f70a0823100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff838116600483015260009216906370a0823190602401602060405180830381865afa158015612968573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061298c9190613eaa565b60035490915073ffffffffffffffffffffffffffffffffffffffff1615612a4e576003546040517f70a0823100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8481166004830152909116906370a0823190602401602060405180830381865afa158015612a1d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a419190613eaa565b612a4b9082613e68565b90505b60045473ffffffffffffffffffffffffffffffffffffffff1615801590612a8c575060085473ffffffffffffffffffffffffffffffffffffffff1615155b15612b3457600480546040517f70a0823100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff858116938201939093529116906370a0823190602401602060405180830381865afa158015612b03573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b279190613eaa565b612b319082613e68565b90505b60005b600c54811015612c26576000600c8281548110612b5657612b56613e7b565b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff1690508015612c1d576040517f70a0823100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff85811660048301528216906370a0823190602401602060405180830381865afa158015612bec573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c109190613eaa565b612c1a9084613e68565b92505b50600101612b37565b50919050565b600554604080517f18160ddd000000000000000000000000000000000000000000000000000000008152905160009273ffffffffffffffffffffffffffffffffffffffff16916318160ddd9160048083019260209291908290030181865afa158015612c9c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612cc09190613eaa565b60035490915073ffffffffffffffffffffffffffffffffffffffff1615612d7f57600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612d4e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d729190613eaa565b612d7c9082613e68565b90505b60045473ffffffffffffffffffffffffffffffffffffffff1615801590612dbd575060085473ffffffffffffffffffffffffffffffffffffffff1615155b15612e6057600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612e2f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612e539190613eaa565b612e5d9082613e68565b90505b60005b600c54811015612f31576000600c8281548110612e8257612e82613e7b565b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff1690508015612f28578073ffffffffffffffffffffffffffffffffffffffff166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612ef7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f1b9190613eaa565b612f259084613e68565b92505b50600101612e63565b5090565b600c54811015612ffa578173ffffffffffffffffffffffffffffffffffffffff16600c8281548110612f6957612f69613e7b565b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff1603612ff2576000600c8281548110612fa557612fa5613e7b565b9060005260206000200160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550612ffa565b600101612f35565b50613003613306565b60405173ffffffffffffffffffffffffffffffffffffffff821681527ff3517f912cde760e82811897047177df419c7aa16326d5710e6b425a8a7d1035906020016112c5565b600060175460000361305b5750600090565b601754620f424060165461306f9190613e16565b6113a69190613e2d565b73ffffffffffffffffffffffffffffffffffffffff821615806130b35750600a5473ffffffffffffffffffffffffffffffffffffffff1615155b156130ea576040517fd08e7ac200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000805473ffffffffffffffffffffffffffffffffffffffff8681167fffffffffffffffffffffffff000000000000000000000000000000000000000092831617909255600a805485841690831681179091556009805483169091179055600b80548684169083161790558251600580548316918416919091179055602083015160068054909216908316179055604082015116158015906131a55750606081015173ffffffffffffffffffffffffffffffffffffffff1615155b156132065760408101516003805473ffffffffffffffffffffffffffffffffffffffff9283167fffffffffffffffffffffffff0000000000000000000000000000000000000000918216179091556060830151600780549190931691161790555b608081015173ffffffffffffffffffffffffffffffffffffffff1615801590613248575060a081015173ffffffffffffffffffffffffffffffffffffffff1615155b156132a95760808101516004805473ffffffffffffffffffffffffffffffffffffffff9283167fffffffffffffffffffffffff00000000000000000000000000000000000000009182161790915560a0830151600880549190931691161790555b505042600f555073ffffffffffffffffffffffffffffffffffffffff16600090815260126020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905562093a80601155565b61330e611663565b601355613319612c2c565b601755613324611615565b600f55565b6040805173ffffffffffffffffffffffffffffffffffffffff85811660248301528416604482015260648082018490528251808303909101815260849091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f23b872dd000000000000000000000000000000000000000000000000000000001790526133be908590613747565b50505050565b6133cc613306565b6133d581613858565b73ffffffffffffffffffffffffffffffffffffffff811660009081526019602052604081205490613405836128f7565b73ffffffffffffffffffffffffffffffffffffffff8416600090815260196020526040812082905590915061343984611db1565b905060008082511115613468578160008151811061345957613459613e7b565b60200260200101516060015190505b6001825111156134f25760005b82518110156134f057816fffffffffffffffffffffffffffffffff168382815181106134a3576134a3613e7b565b6020026020010151606001516fffffffffffffffffffffffffffffffff1610156134e8578281815181106134d9576134d9613e7b565b60200260200101516060015191505b600101613475565b505b73ffffffffffffffffffffffffffffffffffffffff85166000908152601a602052604090206fffffffffffffffffffffffffffffffff8216905583831061355857600061353f8585613dfd565b90508060165461354f9190613e68565b60165550613579565b60006135648486613dfd565b9050806016546135749190613dfd565b601655505b73ffffffffffffffffffffffffffffffffffffffff851660009081526018602052604090205460ff166136025773ffffffffffffffffffffffffffffffffffffffff8516600090815260186020908152604080832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055601b90915290204290555b5050505050565b6040805173ffffffffffffffffffffffffffffffffffffffff8481166024830152604480830185905283518084039091018152606490920183526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb0000000000000000000000000000000000000000000000000000000017905291516000928392908716916136a09190614260565b6000604051808303816000865af19150503d80600081146136dd576040519150601f19603f3d011682016040523d82523d6000602084013e6136e2565b606091505b5091509150811580613710575080511580159061371057508080602001905181019061370e919061427c565b155b15613602576040517f19a9708500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006137a9826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166138bb9092919063ffffffff16565b80519091501561385357808060200190518101906137c7919061427c565b613853576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610c0a565b505050565b73ffffffffffffffffffffffffffffffffffffffff8116156111c357600061387f82610866565b73ffffffffffffffffffffffffffffffffffffffff83166000908152601560209081526040808320939093556013546014909152919020555050565b60606138ca84846000856138d4565b90505b9392505050565b606082471015613966576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610c0a565b73ffffffffffffffffffffffffffffffffffffffff85163b6139e4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610c0a565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051613a0d9190614260565b60006040518083038185875af1925050503d8060008114613a4a576040519150601f19603f3d011682016040523d82523d6000602084013e613a4f565b606091505b5091509150610b0082828660608315613a695750816138cd565b825115613a795782518084602001fd5b816040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c0a9190614299565b73ffffffffffffffffffffffffffffffffffffffff811681146111c357600080fd5b600060208284031215613ae157600080fd5b81356138cd81613aad565b600060c08284031215613afe57600080fd5b8260c083011115612c2657600080fd5b600060208284031215613b2057600080fd5b5035919050565b6020808252825182820181905260009190848201906040850190845b81811015613b7557835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101613b43565b50909695505050505050565b60008060408385031215613b9457600080fd5b8235613b9f81613aad565b946020939093013593505050565b80151581146111c357600080fd5b60008060408385031215613bce57600080fd5b823591506020830135613be081613bad565b809150509250929050565b600060208284031215613bfd57600080fd5b81356138cd81613bad565b602080825282518282018190526000919060409081850190868401855b82811015613c7757815180518552868101516fffffffffffffffffffffffffffffffff9081168887015286820151600f0b87870152606091820151169085015260809093019290850190600101613c25565b5091979650505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60405160c0810167ffffffffffffffff81118282101715613cd657613cd6613c84565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715613d2357613d23613c84565b604052919050565b600080600080610120808688031215613d4357600080fd5b8535613d4e81613aad565b9450602086810135613d5f81613aad565b94506040870135613d6f81613aad565b9350607f87018813613d8057600080fd5b613d88613cb3565b918701918089841115613d9a57600080fd5b606089015b84811015613dbf578035613db281613aad565b8352918301918301613d9f565b50969995985093965050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b81810381811115613e1057613e10613dce565b92915050565b8082028115828204841417613e1057613e10613dce565b600082613e63577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b80820180821115613e1057613e10613dce565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600060208284031215613ebc57600080fd5b5051919050565b8051613ece81613aad565b919050565b600060208284031215613ee557600080fd5b81516138cd81613aad565b80516fffffffffffffffffffffffffffffffff81168114613ece57600080fd5b8051600f81900b8114613ece57600080fd5b600082601f830112613f3357600080fd5b8151602067ffffffffffffffff80831115613f5057613f50613c84565b613f5e828460051b01613cdc565b83815260079390931b85018201928281019087851115613f7d57600080fd5b8387015b8581101561400157608080828b031215613f9b5760008081fd5b60408051918201918683118184101715613fb757613fb7613c84565b82825283518152613fc9888501613ef0565b88820152613fd8828501613f10565b8282015260609250613feb838501613ef0565b9281019290925250835291840191608001613f81565b50979650505050505050565b600082601f83011261401e57600080fd5b6040516060810181811067ffffffffffffffff8211171561404157614041613c84565b60405280606084018581111561405657600080fd5b845b818110156140775761406981613f10565b835260209283019201614058565b509195945050505050565b60006020828403121561409457600080fd5b815167ffffffffffffffff808211156140ac57600080fd5b9083019061010082860312156140c157600080fd5b6140c9613cb3565b6140d283613ec3565b8152602083015160208201526040830151828111156140f057600080fd5b6140fc87828601613f22565b60408301525060608301518281111561411457600080fd5b61412087828601613f22565b60608301525060808301518281111561413857600080fd5b61414487828601613f22565b6080830152506141578660a0850161400d565b60a082015295945050505050565b60006020828403121561417757600080fd5b6138cd82613ef0565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036141b1576141b1613dce565b5060010190565b805167ffffffffffffffff81168114613ece57600080fd5b6000606082840312156141e257600080fd5b6040516060810181811067ffffffffffffffff8211171561420557614205613c84565b60405261421183613ef0565b815261421f602084016141b8565b6020820152614230604084016141b8565b60408201529392505050565b60005b8381101561425757818101518382015260200161423f565b50506000910152565b6000825161427281846020870161423c565b9190910192915050565b60006020828403121561428e57600080fd5b81516138cd81613bad565b60208152600082518060208401526142b881604085016020870161423c565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea2646970667358221220bdc4a560a633ac5b2164af384022d2f11c5e07eac8e8d767d5283a718ff7dd4364736f6c63430008170033
Deployed Bytecode Sourcemap
154192:42666:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;165848:3335;;;;;;:::i;:::-;;:::i;:::-;;;571:25:1;;;559:2;544:18;165848:3335:0;;;;;;;;186910:1298;;;;;;:::i;:::-;;:::i;:::-;;183313:895;;;;;;:::i;:::-;;:::i;157180:49::-;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;1030:14:1;;1023:22;1005:41;;993:2;978:18;157180:49:0;865:187:1;155119:56:0;;;;;;;;;;;;1266:42:1;1254:55;;;1236:74;;1224:2;1209:18;155119:56:0;1057:259:1;100460:141:0;;;;;;:::i;:::-;;:::i;169309:123::-;;;:::i;154807:23::-;;;;;;;;;155697:47;;;;;;:::i;:::-;;;;;;;;;;;;;;;;157850:40;;;;;;:::i;:::-;;;;;;;;;;;;;;;;181841:1159;;;;;;:::i;:::-;;:::i;186531:158::-;;;;;;:::i;:::-;;:::i;157294:56::-;;;;;;:::i;:::-;;;;;;;;;;;;;;155465:30;;;;;;;;;156789:41;;;;;;:::i;:::-;;;;;;;;;;;;;;169539:134;;;:::i;:::-;;;;;;;:::i;100311:29::-;;;;;;;;;156505:34;;;;;;165094:160;;;:::i;155571:35::-;;;;;;:::i;:::-;;:::i;157526:64::-;;;;;;:::i;:::-;;;;;;;;;;;;;;165349:349;;;:::i;156098:24::-;;;;;;164393:608;;;;;;:::i;:::-;;:::i;:::-;;;;2848:25:1;;;2904:2;2889:18;;2882:34;;;;2821:18;164393:608:0;2674:248:1;185834:324:0;;;;;;:::i;:::-;;:::i;154614:29::-;;;;;;;;;100609:354;;;:::i;180525:580::-;;;:::i;156972:38::-;;;;;;185418:306;;;;;;:::i;:::-;;:::i;100284:20::-;;;;;;;;;188661:175;;;;;;:::i;:::-;;:::i;186272:126::-;;;;;;:::i;:::-;;:::i;188320:135::-;;;;;;:::i;:::-;;:::i;170126:6376::-;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;180197:100::-;;;;;;:::i;:::-;;:::i;157077:42::-;;;;;;156617:56;;;;;;:::i;:::-;;;;;;;;;;;;;;158176:41;;;;;;;;;188943:114;;;;;;:::i;:::-;;:::i;169788:127::-;169882:18;:25;169788:127;;180342:77;;;:::i;155997:29::-;;;;;;156323:47;;;;;;:::i;:::-;;;;;;;;;;;;;;;;161942:949;;;;;;:::i;:::-;;:::i;156183:28::-;;;;;;155243:25;;;;;;;;;155875:27;;;;;;154731:23;;;;;;;;;163132:972;;;:::i;155381:34::-;;;;;;;;;154894:33;;;;;;;;;155002;;;;;;;;;161490:236;;;:::i;159692:1482::-;;;;;;:::i;:::-;;:::i;181159:560::-;;;:::i;165848:3335::-;166085:27;;;165903:15;166085:27;;;:17;:27;;;;;;;;166080:42;;-1:-1:-1;166121:1:0;;165848:3335;-1:-1:-1;165848:3335:0:o;166080:42::-;166176:28;166206:23;166233:30;166254:8;166233:20;:30::i;:::-;166175:88;;-1:-1:-1;166175:88:0;-1:-1:-1;158040:3:0;166314:28;166449:25;;;166445:1228;;166786:29;;;;;;;:19;:29;;;;;;:48;-1:-1:-1;166782:880:0;;-1:-1:-1;166923:1:0;;165848:3335;-1:-1:-1;;;;165848:3335:0:o;166782:880::-;167237:29;;;167196:20;167237:29;;;:19;:29;;;;;;167219:47;;:15;:47;:::i;:::-;167389:29;;;167351:17;167389:29;;;:19;:29;;;;;;167196:70;;-1:-1:-1;167351:17:0;167371:47;;:15;:47;:::i;:::-;167351:67;-1:-1:-1;167351:67:0;167521:30;167539:12;158040:3;167521:30;:::i;:::-;167520:44;;;;:::i;:::-;167497:67;;166999:663;;166782:880;167872:31;;;167810:25;167872:31;;;:21;:31;;;;;;168050:38;;;168046:909;;;168175:15;168155:35;;168046:909;;;168432:1;168390:38;168413:15;168390:20;:38;:::i;:::-;168389:44;;;;:::i;:::-;168843:16;;;168622:25;168843:16;;;:6;:16;;;;;;168369:64;;-1:-1:-1;168622:25:0;168800:22;158040:3;168800:4;:22;:::i;:::-;168706:31;;;;;;;:21;:31;;;;;;168758:20;;168688:15;:13;:15::i;:::-;:49;;;;:::i;:::-;168652:86;;:15;:86;:::i;:::-;:126;;;;:::i;:::-;168651:172;;;;:::i;:::-;:208;;;;:::i;:::-;-1:-1:-1;;168046:909:0;169158:16;;;;;;;:6;:16;;;;;;169119:22;158040:3;169119:4;:22;:::i;:::-;169046:31;;;;;;;:21;:31;;;;;;169081:20;;169028:15;:13;:15::i;:::-;:49;;;;:::i;:::-;169007:71;;:17;:71;:::i;:::-;:94;;;;:::i;:::-;169006:136;;;;:::i;:::-;:168;;;;:::i;:::-;168998:177;165848:3335;-1:-1:-1;;;;;;;165848:3335:0:o;186910:1298::-;158670:5;;;;158656:10;:19;;;;:52;;-1:-1:-1;158693:15:0;;;;158679:10;:29;;158656:52;158652:85;;;158717:20;;;;;;;;;;;;;;158652:85;187112:1:::1;187085:15;;::::0;::::1;:12:::0;:15:::1;:::i;:::-;:29;;::::0;187077:63:::1;;;::::0;::::1;::::0;;9497:2:1;187077:63:0::1;::::0;::::1;9479:21:1::0;9536:2;9516:18;;;9509:30;9575:23;9555:18;;;9548:51;9616:18;;187077:63:0::1;;;;;;;;;187186:1;187159:15;::::0;;;::::1;::::0;::::1;;:::i;:::-;:29;;::::0;187151:68:::1;;;::::0;::::1;::::0;;9847:2:1;187151:68:0::1;::::0;::::1;9829:21:1::0;9886:2;9866:18;;;9859:30;9925:28;9905:18;;;9898:56;9971:18;;187151:68:0::1;9645:350:1::0;187151:68:0::1;187265:1;187238:15;::::0;;;;;::::1;;:::i;:::-;:29;;;187230:67;;;::::0;::::1;::::0;;10202:2:1;187230:67:0::1;::::0;::::1;10184:21:1::0;10241:2;10221:18;;;10214:30;10280:27;10260:18;;;10253:55;10325:18;;187230:67:0::1;10000:349:1::0;187230:67:0::1;187343:1;187316:15;::::0;;;;;::::1;;:::i;:::-;:29;;;187308:72;;;::::0;::::1;::::0;;10556:2:1;187308:72:0::1;::::0;::::1;10538:21:1::0;10595:2;10575:18;;;10568:30;10634:32;10614:18;;;10607:60;10684:18;;187308:72:0::1;10354:354:1::0;187308:72:0::1;187426:1;187399:15;::::0;;;;;::::1;;:::i;:::-;:29;;;187391:64;;;::::0;::::1;::::0;;10915:2:1;187391:64:0::1;::::0;::::1;10897:21:1::0;10954:2;10934:18;;;10927:30;10993:24;10973:18;;;10966:52;11035:18;;187391:64:0::1;10713:346:1::0;187391:64:0::1;187501:1;187474:15;::::0;;;;;::::1;;:::i;:::-;:29;;;187466:81;;;::::0;::::1;::::0;;11266:2:1;187466:81:0::1;::::0;::::1;11248:21:1::0;11305:2;11285:18;;;11278:30;11344:34;11324:18;;;11317:62;11415:9;11395:18;;;11388:37;11442:19;;187466:81:0::1;11064:403:1::0;187466:81:0::1;187616:15;;::::0;::::1;:12:::0;:15:::1;:::i;:::-;187597:5;:35:::0;;;::::1;;::::0;;;::::1;::::0;;;::::1;::::0;;187672:15:::1;::::0;;;::::1;::::0;::::1;;:::i;:::-;187643:10;:45:::0;;;::::1;;::::0;;;::::1;::::0;;;::::1;::::0;;-1:-1:-1;187730:15:0::1;::::0;;;;;::::1;;:::i;:::-;:29;;;;187729:64;;;;-1:-1:-1::0;187791:1:0::1;187764:15;::::0;;;;;::::1;;:::i;:::-;:29;;;;187729:64;187725:198;;;187835:15;::::0;;;;;::::1;;:::i;:::-;187810:10;:41:::0;;;::::1;;::::0;;;::::1;::::0;;;::::1;::::0;;187895:15:::1;::::0;;;;;::::1;;:::i;:::-;187866:10;:45:::0;;;::::1;;::::0;;;::::1;::::0;;;::::1;::::0;;187725:198:::1;188016:1;187989:15;::::0;;;;;::::1;;:::i;:::-;:29;;;;187988:66;;;;-1:-1:-1::0;188051:1:0::1;188024:15;::::0;;;;;::::1;;:::i;:::-;:29;;;;187988:66;187984:217;;;188090:15;::::0;;;;;::::1;;:::i;:::-;188071:7;:35:::0;;;::::1;;::::0;;;::::1;::::0;;;::::1;::::0;;188173:15:::1;::::0;;;;;::::1;;:::i;:::-;188121:24;:68:::0;;;::::1;;::::0;;;::::1;::::0;;;::::1;::::0;;187984:217:::1;186910:1298:::0;:::o;183313:895::-;158670:5;;;;158656:10;:19;;;;:52;;-1:-1:-1;158693:15:0;;;;158679:10;:29;;158656:52;158652:85;;;158717:20;;;;;;;;;;;;;;158652:85;183467:64:::1;::::0;::::1;::::0;;11674:2:1;183467:64:0::1;::::0;::::1;11656:21:1::0;11713:2;11693:18;;;11686:30;11752:34;11732:18;;;11725:62;11823:16;11803:18;;;11796:44;11857:19;;183467:64:0::1;11472:410:1::0;184171:29:0::1;;;;;;;;183313:895:::0;:::o;100460:141::-;101114:5;;;;101100:10;:19;101096:43;;101128:11;;;;;;;;;;;;;;101096:43;100532:14:::1;:23:::0;;;::::1;;::::0;::::1;::::0;;::::1;::::0;;;100571:22:::1;::::0;1236:74:1;;;100571:22:0::1;::::0;1224:2:1;1209:18;100571:22:0::1;1057:259:1::0;169309:123:0;169363:14;169410:13;;169398:9;;:25;;;;:::i;:::-;169390:34;;169309:123;:::o;181841:1159::-;181985:10;181969:27;;;;:15;:27;;;;;;;;181964:60;;182005:19;;;;;;;;;;;;;;181964:60;182211:12;;:65;;:12;;182241:10;182261:4;182268:7;182211:29;:65::i;:::-;182331:6;:4;:6::i;:::-;182410:12;;182391:15;:31;182387:300;;182461:13;;182451:23;;:7;:23;:::i;:::-;182439:9;:35;182387:300;;;182507:17;182542:15;182527:12;;:30;;;;:::i;:::-;182507:50;;182572:16;182603:9;;182591;:21;;;;:::i;:::-;182662:13;;182572:40;;-1:-1:-1;182640:18:0;182572:40;182640:7;:18;:::i;:::-;182639:36;;;;:::i;:::-;182627:9;:48;-1:-1:-1;;182387:300:0;182757:15;182740:14;:32;;;182816:13;;182798:31;;;:::i;:::-;182783:12;:46;182914:29;:27;:29::i;:::-;182884:27;:59;182982:9;;182961:31;;;2848:25:1;;;2904:2;2889:18;;2882:34;;;;182961:31:0;;2821:18:1;182961:31:0;2674:248:1;186531:158:0;158670:5;;;;158656:10;:19;;;;:52;;-1:-1:-1;158693:15:0;;;;158679:10;:29;;158656:52;158652:85;;;158717:20;;;;;;;;;;;;;;158652:85;186651:30:::1;;;::::0;;;:15:::1;:30;::::0;;;;;;186617:64;;::::1;186651:30;::::0;;::::1;186650:31;186617:64;::::0;;186531:158::o;169539:134::-;169600:27;169647:18;169640:25;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;169539:134;:::o;165094:160::-;165150:11;165200:12;;165182:15;:30;:63;;-1:-1:-1;165233:12:0;;;169309:123::o;165182:63::-;-1:-1:-1;165215:15:0;;165094:160::o;155571:35::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;155571:35:0;:::o;165349:349::-;165395:14;165426:27;;165457:1;165426:32;165422:269;;-1:-1:-1;165482:19:0;;;165349:349::o;165422:269::-;165650:27;;165630:9;;165612:14;;165584:25;:23;:25::i;:::-;:42;;;;:::i;:::-;165583:56;;;;:::i;:::-;:63;;165642:4;165583:63;:::i;:::-;165582:95;;;;:::i;:::-;165542:19;;:136;;;;:::i;164393:608::-;164475:25;164502:30;164603:21;164627:23;164644:5;164627:16;:23::i;:::-;164732:36;;;;;;;:29;:36;;;;;;;-1:-1:-1;164603:47:0;-1:-1:-1;164837:15:0;:41;-1:-1:-1;164833:161:0;;164915:1;164895:21;;164833:161;;;164969:13;164949:33;;164833:161;164534:467;164393:608;;;:::o;185834:324::-;158670:5;;;;158656:10;:19;;;;:52;;-1:-1:-1;158693:15:0;;;;158679:10;:29;;158656:52;158652:85;;;158717:20;;;;;;;;;;;;;;158652:85;185921:12:::1;::::0;:17;;::::1;::::0;:52:::1;;;185961:12;;185942:15;:31;;185921:52;185917:142;;;185997:50;;;;;;;;;;;;;;185917:142;186069:13;:30:::0;;;186115:35:::1;::::0;571:25:1;;;186115:35:0::1;::::0;559:2:1;544:18;186115:35:0::1;425:177:1::0;100609:354:0;100782:14;;;;100768:10;:28;100764:69;;100805:28;;;;;;;;;;;;;;100764:69;100862:5;;;100869:14;100849:35;;;100862:5;;;;17894:34:1;;100869:14:0;;;;17959:2:1;17944:18;;17937:43;100849:35:0;;17806:18:1;100849:35:0;;;;;;;100903:14;;;;100895:22;;;;;;100903:14;;;100895:22;;;;100928:27;;;100609:354::o;180525:580::-;180673:15;73099:1;73697:7;;:19;73689:63;;;;;;;18193:2:1;73689:63:0;;;18175:21:1;18232:2;18212:18;;;18205:30;18271:33;18251:18;;;18244:61;18322:18;;73689:63:0;17991:355:1;73689:63:0;73099:1;73830:18;;158874:21:::1;::::0;::::1;;158870:57;;;158904:23;;;;;;;;;;;;;;158870:57;180643:10:::2;159044:24;159060:7;159044:15;:24::i;:::-;180719:10:::3;180710:20;::::0;;;:8:::3;:20;::::0;;;;;::::3;;180706:52;;;180739:19;;;;;;;;;;;;;;180706:52;180788:10;180781:18;::::0;;;:6:::3;:18;::::0;;;;;;-1:-1:-1;180814:11:0;;180810:226:::3;;180849:10;180863:1;180842:18:::0;;;:6:::3;:18;::::0;;;;:22;180907:19:::3;::::0;180879:69:::3;::::0;180842:18:::3;180907:19:::0;;::::3;::::0;180940:7;180879:27:::3;:69::i;:::-;181004:19;::::0;180968:56:::3;::::0;;18525:25:1;;;180968:56:0::3;181004:19:::0;;::::3;18581:2:1::0;18566:18;;18559:83;180983:10:0::3;::::0;180968:56:::3;::::0;18498:18:1;180968:56:0::3;;;;;;;180810:226;-1:-1:-1::0;181068:10:0::3;181048:31;::::0;;;:19:::3;:31;::::0;;;;181082:15:::3;181048:49:::0;;73055:1;74009:7;:22;180525:580;:::o;185418:306::-;158670:5;;;;158656:10;:19;;;;:52;;-1:-1:-1;158693:15:0;;;;158679:10;:29;;158656:52;158652:85;;;158717:20;;;;;;;;;;;;;;158652:85;185637:5:::1;::::0;185594:63:::1;::::0;185622:13;;185637:5:::1;;185644:12:::0;185594:27:::1;:63::i;:::-;185673:43;::::0;;18857:42:1;18845:55;;18827:74;;18932:2;18917:18;;18910:34;;;185673:43:0::1;::::0;18800:18:1;185673:43:0::1;;;;;;;185418:306:::0;;:::o;188661:175::-;158670:5;;;;158656:10;:19;;;;:52;;-1:-1:-1;158693:15:0;;;;158679:10;:29;;158656:52;158652:85;;;158717:20;;;;;;;;;;;;;;158652:85;188749:9:::1;:20:::0;;;188782:47;::::1;;;188811:6;:4;:6::i;:::-;188661:175:::0;;:::o;186272:126::-;158670:5;;;;158656:10;:19;;;;:52;;-1:-1:-1;158693:15:0;;;;158679:10;:29;;158656:52;158652:85;;;158717:20;;;;;;;;;;;;;;158652:85;186371:18:::1;;;::::0;;;:8:::1;:18;::::0;;;;;;186348:42;;::::1;186371:18;::::0;;::::1;186369:21;186348:42;::::0;;186272:126::o;188320:135::-;158670:5;;;;158656:10;:19;;;;:52;;-1:-1:-1;158693:15:0;;;;158679:10;:29;;158656:52;158652:85;;;158717:20;;;;;;;;;;;;;;158652:85;188401:21:::1;:46:::0;;;::::1;::::0;::::1;;::::0;;;::::1;::::0;;188320:135::o;170126:6376::-;170494:5;;:24;;;;;:5;1254:55:1;;;170494:24:0;;;1236:74:1;170212:47:0;;170472:19;;170494:5;;;:14;;1209:18:1;;170494:24:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;170578:10;;170472:46;;;;;;-1:-1:-1;170570:33:0;170578:10;170570:33;170566:83;;170620:10;;:29;;;;;:10;1254:55:1;;;170620:29:0;;;1236:74:1;170620:10:0;;;;:19;;1209:18:1;;170620:29:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;170605:44;;;;;;:::i;:::-;;;170566:83;170706:7;;170698:30;170706:7;170698:30;;;;170697:85;;-1:-1:-1;170742:24:0;;170734:47;170742:24;170734:47;;170697:85;170693:179;;;170799:16;170814:1;170799:16;;:::i;:::-;;;170693:179;170976:9;170971:301;170995:18;:25;170991:29;;170971:301;;;171042:15;171060:18;171079:1;171060:21;;;;;;;;:::i;:::-;;;;;;;;;;;;;;-1:-1:-1;171100:21:0;;171096:165;;171207:38;;;;;:28;1254:55:1;;;171207:38:0;;;1236:74:1;171207:28:0;;;;;1209:18:1;;171207:38:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;171192:53;;;;;;:::i;:::-;;;171096:165;-1:-1:-1;171022:3:0;;170971:301;;;;171331:22;171368:46;171445:11;171417:40;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;171417:40:0;;;;;;;;;;;;;;-1:-1:-1;171703:10:0;;:44;;;;;:10;1254:55:1;;;171703:44:0;;;1236:74:1;171368:89:0;;-1:-1:-1;171644:55:0;;171703:10;;;;:34;;1209:18:1;;171703:44:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;171702:76;;;171644:134;;171887:9;171882:624;171902:24;:31;171898:1;:35;171882:624;;;172004:61;172068:24;172093:1;172068:27;;;;;;;;:::i;:::-;;;;;;;172004:91;;172286:18;172252:15;172268:14;172252:31;;;;;;;;:::i;:::-;;;;;;:52;;;;172376:16;;;;:::i;:::-;;-1:-1:-1;;172468:3:0;;171882:624;;;-1:-1:-1;;172614:10:0;;172606:33;172614:10;172606:33;172602:1321;;172795:10;;:44;;;;;:10;1254:55:1;;;172795:44:0;;;1236:74:1;172703:70:0;;172795:10;;:34;;1209:18:1;;172795:44:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;172776:90;;;172703:163;;172973:9;172968:944;172988:25;:32;172984:1;:36;172968:944;;;173091:56;173150:25;173176:1;173150:28;;;;;;;;:::i;:::-;;;;;;;173091:87;;173265:15;173245:13;:17;;;:35;;;173241:580;;;173441:264;;;;;;;;173508:13;:16;;;173441:264;;;;173558:13;:19;;;173441:264;;;;;;173612:13;:20;;;173441:264;;;;;;173664:13;:17;;;173441:264;;;;;173407:15;173423:14;173407:31;;;;;;;;:::i;:::-;;;;;;:298;;;;173785:16;;;;:::i;:::-;;;173241:580;-1:-1:-1;173874:3:0;;172968:944;;;;172641:1282;172602:1321;174017:7;;174009:30;174017:7;174009:30;;;;174008:85;;-1:-1:-1;174053:24:0;;174045:47;174053:24;174045:47;;174008:85;174004:790;;;174197:7;;;:24;;;;;:7;1254:55:1;;;174197:24:0;;;1236:74:1;;;;174148:46:0;;174197:7;;;;:14;;1209:18:1;;174197:24:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;174148:73;;174398:15;174375:16;:20;;;:38;;;174371:412;;;174468:211;;;;;;;;174517:1;174468:211;;;;174548:1;174468:211;;;;;;174587:16;:23;;;174468:211;;;;;;174639:16;:20;;;174468:211;;;;;;;174434:15;174450:14;174434:31;;;;;;;;:::i;:::-;;;;;;:245;;;;174751:16;;;;:::i;:::-;;;174371:412;174095:699;174004:790;174916:9;174911:1210;174935:18;:25;174931:29;;174911:1210;;;174982:15;175000:18;175019:1;175000:21;;;;;;;;:::i;:::-;;;;;;;;;;;;;;-1:-1:-1;175040:21:0;;175036:1074;;175123:55;175231:7;175220:30;;;:32;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;175204:83;;;;;:73;1254:55:1;;;175204:83:0;;;1236:74:1;175204:73:0;;;;;;;1209:18:1;;175204:83:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;175181:137;;;175123:195;;175428:9;175423:672;175443:24;:31;175439:1;:35;175423:672;;;175553:60;175616:24;175641:1;175616:27;;;;;;;;:::i;:::-;;;;;;;175553:90;;175848:17;175814:15;175830:14;175814:31;;;;;;;;:::i;:::-;;;;;;:51;;;;175945:16;;;;:::i;:::-;;-1:-1:-1;;176049:3:0;;175423:672;;;;175063:1047;175036:1074;-1:-1:-1;174962:3:0;;174911:1210;;;;176255:14;176227:43;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;176227:43:0;;;;;;;;;;;;;;;176208:62;;176322:9;176317:178;176337:16;:23;176333:1;:27;176317:178;;;176401:15;176417:1;176401:18;;;;;;;;:::i;:::-;;;;;;;176379:16;176396:1;176379:19;;;;;;;;:::i;:::-;;;;;;;;;;:40;176465:3;;176317:178;;;;170261:6241;;;170126:6376;;;:::o;180197:100::-;180264:25;180280:8;180264:15;:25::i;188943:114::-;158670:5;;;;158656:10;:19;;;;:52;;-1:-1:-1;158693:15:0;;;;158679:10;:29;;158656:52;158652:85;;;158717:20;;;;;;;;;;;;;;158652:85;189019:15:::1;:30:::0;;;::::1;;::::0;;;::::1;::::0;;;::::1;::::0;;188943:114::o;180342:77::-;180384:27;180400:10;180384:15;:27::i;:::-;180342:77::o;161942:949::-;162160:5;;:22;;;;;:5;1254:55:1;;;162160:22:0;;;1236:74:1;162004:16:0;;162160:5;;:15;;1209:18:1;;162160:22:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;162253:10;;162149:33;;-1:-1:-1;162245:33:0;162253:10;162245:33;162241:78;;162292:10;;:27;;;;;:10;1254:55:1;;;162292:27:0;;;1236:74:1;162292:10:0;;;;:20;;1209:18:1;;162292:27:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;162280:39;;;;:::i;:::-;;;162241:78;162430:7;;162422:30;162430:7;162422:30;;;;162421:85;;-1:-1:-1;162466:24:0;;162458:47;162466:24;162458:47;;162421:85;162417:154;;;162535:7;;;:24;;;;;:7;1254:55:1;;;162535:24:0;;;1236:74:1;;;;162535:7:0;;;:17;;1209:18:1;;162535:24:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;162523:36;;;;:::i;:::-;;;162417:154;162643:9;162638:246;162662:18;:25;162658:29;;162638:246;;;162709:15;162727:18;162746:1;162727:21;;;;;;;;:::i;:::-;;;;;;;;;;;;;;-1:-1:-1;162767:21:0;;162763:110;;162821:36;;;;;:29;1254:55:1;;;162821:36:0;;;1236:74:1;162821:29:0;;;;;1209:18:1;;162821:36:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;162809:48;;;;:::i;:::-;;;162763:110;-1:-1:-1;162689:3:0;;162638:246;;;;161942:949;;;:::o;163132:972::-;163356:5;;:19;;;;;;;;163192:20;;163356:5;;;:17;;:19;;;;;;;;;;;;;;:5;:19;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;163446:10;;163341:34;;-1:-1:-1;163438:33:0;163446:10;163438:33;163434:79;;163489:10;;;;;;;;;;;:22;;;:24;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;163473:40;;;;:::i;:::-;;;163434:79;163624:7;;163616:30;163624:7;163616:30;;;;163615:85;;-1:-1:-1;163660:24:0;;163652:47;163660:24;163652:47;;163615:85;163611:172;;;163733:24;;;;;;;;;;;:36;;;:38;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;163717:54;;;;:::i;:::-;;;163611:172;163855:9;163850:247;163874:18;:25;163870:29;;163850:247;;;163921:15;163939:18;163958:1;163939:21;;;;;;;;:::i;:::-;;;;;;;;;;;;;;-1:-1:-1;163979:21:0;;163975:111;;164048:7;164037:31;;;:33;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;164021:49;;;;:::i;:::-;;;163975:111;-1:-1:-1;163901:3:0;;163850:247;;;;163132:972;:::o;184825:280::-:1;184849:18;:25:::0;184845:29;::::1;184825:280;;;184925:5;184900:30;;:18;184919:1;184900:21;;;;;;;;:::i;:::-;;::::0;;;::::1;::::0;;;::::1;::::0;::::1;;:30:::0;184896:198:::1;;184983:1;184951:18;184970:1;184951:21;;;;;;;;:::i;:::-;;;;;;;;;:34;;;;;;;;;;;;;;;;;;185073:5;;184896:198;184876:3;;184825:280;;;;185117:6;:4;:6::i;:::-;185141:31;::::0;1266:42:1;1254:55;;1236:74;;185141:31:0::1;::::0;1224:2:1;1209:18;185141:31:0::1;1057:259:1::0;161490:236:0;161546:17;161580:27;;161611:1;161580:32;161576:142;;-1:-1:-1;161621:1:0;;161490:236::o;161576:142::-;161691:27;;158040:3;161646:23;;:41;;;;:::i;:::-;161645:73;;;;:::i;159692:1482::-;159967:27;;;;;:64;;-1:-1:-1;159998:19:0;;:33;:19;:33;;159967:64;159963:122;;;160055:18;;;;;;;;;;;;;;159963:122;160131:5;:14;;;;;;;;;;;;;;160189:19;:35;;;;;;;;;;;;;160235:12;:35;;;;;;;;;160281:15;:34;;;;;;;;;;;160385:15;;160366:5;:35;;;;;;;;;;;;;160385:15;160441;;;-1:-1:-1;160412:45:0;;;;;;;;;;;160517:15;;;;:29;;;;;160516:66;;-1:-1:-1;160552:15:0;;;;:29;;;;160516:66;160512:200;;;160624:15;;;;160599:10;:41;;;;;;;;;;;;;;160684:15;;;;160655:10;:45;;;;;;;;;;;160512:200;160796:15;;;;:29;;;;;;160795:66;;-1:-1:-1;160831:15:0;;;;:29;;;;160795:66;160791:217;;;160897:15;;;;160910:1;160878:35;;;;;;;;;;;;;;160980:15;;;;160928:24;:68;;;;;;;;;;;160791:217;-1:-1:-1;;161076:15:0;161059:14;:32;-1:-1:-1;161102:23:0;;;;;;:15;:23;;;;;:30;;;;161128:4;161102:30;;;161159:7;161143:13;:23;159692:1482::o;181159:560::-;181318:15;:13;:15::i;:::-;181296:19;:37;181486:29;:27;:29::i;:::-;181456:27;:59;181640:25;:23;:25::i;:::-;181623:14;:42;181159:560::o;135769:248::-;135940:68;;;22055:42:1;22124:15;;;135940:68:0;;;22106:34:1;22176:15;;22156:18;;;22149:43;22208:18;;;;22201:34;;;135940:68:0;;;;;;;;;;22018:18:1;;;;135940:68:0;;;;;;;;;;135963:27;135940:68;;;135913:96;;135933:5;;135913:19;:96::i;:::-;135769:248;;;;:::o;176910:2831::-;177074:6;:4;:6::i;:::-;177134:21;177146:8;177134:11;:21::i;:::-;177246:31;;;177219:24;177246:31;;;:21;:31;;;;;;;177375:26;177268:8;177375:16;:26::i;:::-;177465:31;;;;;;;:21;:31;;;;;:50;;;177348:53;;-1:-1:-1;177624:31:0;177487:8;177624:21;:31::i;:::-;177565:90;;177995:30;178132:1;178097:25;:32;:36;178093:192;;;178241:25;178267:1;178241:28;;;;;;;;:::i;:::-;;;;;;;:32;;;178216:57;;178093:192;178397:1;178362:25;:32;:36;178358:569;;;178486:9;178481:435;178501:25;:32;178497:1;:36;178481:435;;;178701:22;178666:57;;:25;178692:1;178666:28;;;;;;;;:::i;:::-;;;;;;;:32;;;:57;;;178662:163;;;178773:25;178799:1;178773:28;;;;;;;;:::i;:::-;;;;;;;:32;;;178748:57;;178662:163;178878:3;;178481:435;;;;178358:569;179029:39;;;;;;;:29;:39;;;;;:64;;;;;179160:36;;;179156:368;;179213:18;179234:35;179253:16;179234;:35;:::i;:::-;179213:56;;179336:10;179310:23;;:36;;;;:::i;:::-;179284:23;:62;-1:-1:-1;179156:368:0;;;179379:18;179400:35;179419:16;179400;:35;:::i;:::-;179379:56;;179502:10;179476:23;;:36;;;;:::i;:::-;179450:23;:62;-1:-1:-1;179156:368:0;179582:27;;;;;;;:17;:27;;;;;;;;179577:157;;179626:27;;;;;;;:17;:27;;;;;;;;:34;;;;179656:4;179626:34;;;179675:19;:29;;;;;179707:15;179675:47;;179577:157;176962:2779;;;;176910:2831;:::o;93398:480::-;93596:45;;;93585:10;18845:55:1;;;93596:45:0;;;18827:74:1;18917:18;;;;18910:34;;;93596:45:0;;;;;;;;;;18800:18:1;;;;93596:45:0;;;;;;;;;;;;;93585:57;;-1:-1:-1;;;;93585:10:0;;;;:57;;93596:45;93585:57;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;93549:93;;;;93773:7;93772:8;:59;;;-1:-1:-1;93785:11:0;;:16;;;;:45;;;93817:4;93806:24;;;;;;;;;;;;:::i;:::-;93805:25;93785:45;93768:102;;;93840:30;;;;;;;;;;;;;;138617:716;139041:23;139067:69;139095:4;139067:69;;;;;;;;;;;;;;;;;139075:5;139067:27;;;;:69;;;;;:::i;:::-;139151:17;;139041:95;;-1:-1:-1;139151:21:0;139147:179;;139248:10;139237:30;;;;;;;;;;;;:::i;:::-;139229:85;;;;;;;23245:2:1;139229:85:0;;;23227:21:1;23284:2;23264:18;;;23257:30;23323:34;23303:18;;;23296:62;23394:12;23374:18;;;23367:40;23424:19;;139229:85:0;23043:406:1;139229:85:0;138687:646;138617:716;;:::o;179831:264::-;179894:22;;;;179890:198;;179933:15;179951:16;179958:8;179951:6;:16::i;:::-;179982;;;;;;;:6;:16;;;;;;;;:26;;;;180057:19;;180023:21;:31;;;;;;:53;-1:-1:-1;179831:264:0;:::o;83202:229::-;83339:12;83371:52;83393:6;83401:4;83407:1;83410:12;83371:21;:52::i;:::-;83364:59;;83202:229;;;;;;:::o;84322:510::-;84492:12;84550:5;84525:21;:30;;84517:81;;;;;;;23656:2:1;84517:81:0;;;23638:21:1;23695:2;23675:18;;;23668:30;23734:34;23714:18;;;23707:62;23805:8;23785:18;;;23778:36;23831:19;;84517:81:0;23454:402:1;84517:81:0;80752:19;;;;84609:60;;;;;;;24063:2:1;84609:60:0;;;24045:21:1;24102:2;24082:18;;;24075:30;24141:31;24121:18;;;24114:59;24190:18;;84609:60:0;23861:353:1;84609:60:0;84683:12;84697:23;84724:6;:11;;84743:5;84750:4;84724:31;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;84682:73;;;;84773:51;84790:7;84799:10;84811:12;87158;87187:7;87183:580;;;-1:-1:-1;87218:10:0;87211:17;;87183:580;87332:17;;:21;87328:424;;87580:10;87574:17;87641:15;87628:10;87624:2;87620:19;87613:44;87328:424;87723:12;87716:20;;;;;;;;;;;:::i;14:154:1:-;100:42;93:5;89:54;82:5;79:65;69:93;;158:1;155;148:12;173:247;232:6;285:2;273:9;264:7;260:23;256:32;253:52;;;301:1;298;291:12;253:52;340:9;327:23;359:31;384:5;359:31;:::i;607:253::-;691:6;744:3;732:9;723:7;719:23;715:33;712:53;;;761:1;758;751:12;712:53;801:7;795:3;784:9;780:19;777:32;774:52;;;822:1;819;812:12;1572:180;1631:6;1684:2;1672:9;1663:7;1659:23;1655:32;1652:52;;;1700:1;1697;1690:12;1652:52;-1:-1:-1;1723:23:1;;1572:180;-1:-1:-1;1572:180:1:o;1988:681::-;2159:2;2211:21;;;2281:13;;2184:18;;;2303:22;;;2130:4;;2159:2;2382:15;;;;2356:2;2341:18;;;2130:4;2425:218;2439:6;2436:1;2433:13;2425:218;;;2504:13;;2519:42;2500:62;2488:75;;2618:15;;;;2583:12;;;;2461:1;2454:9;2425:218;;;-1:-1:-1;2660:3:1;;1988:681;-1:-1:-1;;;;;;1988:681:1:o;3178:315::-;3246:6;3254;3307:2;3295:9;3286:7;3282:23;3278:32;3275:52;;;3323:1;3320;3313:12;3275:52;3362:9;3349:23;3381:31;3406:5;3381:31;:::i;:::-;3431:5;3483:2;3468:18;;;;3455:32;;-1:-1:-1;;;3178:315:1:o;3498:118::-;3584:5;3577:13;3570:21;3563:5;3560:32;3550:60;;3606:1;3603;3596:12;3621:309;3686:6;3694;3747:2;3735:9;3726:7;3722:23;3718:32;3715:52;;;3763:1;3760;3753:12;3715:52;3799:9;3786:23;3776:33;;3859:2;3848:9;3844:18;3831:32;3872:28;3894:5;3872:28;:::i;:::-;3919:5;3909:15;;;3621:309;;;;;:::o;3935:241::-;3991:6;4044:2;4032:9;4023:7;4019:23;4015:32;4012:52;;;4060:1;4057;4050:12;4012:52;4099:9;4086:23;4118:28;4140:5;4118:28;:::i;4181:1087::-;4430:2;4482:21;;;4552:13;;4455:18;;;4574:22;;;4401:4;;4430:2;4615;;4633:18;;;;4674:15;;;4401:4;4717:525;4731:6;4728:1;4725:13;4717:525;;;4790:13;;4828:9;;4816:22;;4877:11;;;4871:18;4912:34;4980:21;;;4966:12;;;4959:43;5057:11;;;5051:18;5047:2;5036:34;5022:12;;;5015:56;5094:4;5142:11;;;5136:18;5132:27;5118:12;;;5111:49;5189:4;5180:14;;;;5217:15;;;;4753:1;4746:9;4717:525;;;-1:-1:-1;5259:3:1;;4181:1087;-1:-1:-1;;;;;;;4181:1087:1:o;6279:184::-;6331:77;6328:1;6321:88;6428:4;6425:1;6418:15;6452:4;6449:1;6442:15;6468:253;6540:2;6534:9;6582:4;6570:17;;6617:18;6602:34;;6638:22;;;6599:62;6596:88;;;6664:18;;:::i;:::-;6700:2;6693:22;6468:253;:::o;6726:334::-;6797:2;6791:9;6853:2;6843:13;;6858:66;6839:86;6827:99;;6956:18;6941:34;;6977:22;;;6938:62;6935:88;;;7003:18;;:::i;:::-;7039:2;7032:22;6726:334;;-1:-1:-1;6726:334:1:o;7065:1132::-;7174:6;7182;7190;7198;7229:3;7273:2;7261:9;7252:7;7248:23;7244:32;7241:52;;;7289:1;7286;7279:12;7241:52;7328:9;7315:23;7347:31;7372:5;7347:31;:::i;:::-;7397:5;-1:-1:-1;7421:2:1;7460:18;;;7447:32;7488:33;7447:32;7488:33;:::i;:::-;7540:7;-1:-1:-1;7599:2:1;7584:18;;7571:32;7612:33;7571:32;7612:33;:::i;:::-;7664:7;-1:-1:-1;7709:3:1;7694:19;;7690:33;-1:-1:-1;7680:61:1;;7737:1;7734;7727:12;7680:61;7761:22;;:::i;:::-;7831:18;;;;7805:3;7861:19;;;7858:39;;;7893:1;7890;7883:12;7858:39;7932:2;7921:9;7917:18;7944:223;7960:6;7955:3;7952:15;7944:223;;;8042:3;8029:17;8059:33;8084:7;8059:33;:::i;:::-;8105:20;;8145:12;;;;7977;;7944:223;;;-1:-1:-1;7065:1132:1;;;;-1:-1:-1;7065:1132:1;;-1:-1:-1;;;;;7065:1132:1:o;8202:184::-;8254:77;8251:1;8244:88;8351:4;8348:1;8341:15;8375:4;8372:1;8365:15;8391:128;8458:9;;;8479:11;;;8476:37;;;8493:18;;:::i;:::-;8391:128;;;;:::o;8524:168::-;8597:9;;;8628;;8645:15;;;8639:22;;8625:37;8615:71;;8666:18;;:::i;8697:274::-;8737:1;8763;8753:189;;8798:77;8795:1;8788:88;8899:4;8896:1;8889:15;8927:4;8924:1;8917:15;8753:189;-1:-1:-1;8956:9:1;;8697:274::o;8976:125::-;9041:9;;;9062:10;;;9059:36;;;9075:18;;:::i;9106:184::-;9158:77;9155:1;9148:88;9255:4;9252:1;9245:15;9279:4;9276:1;9269:15;12237:184;12307:6;12360:2;12348:9;12339:7;12335:23;12331:32;12328:52;;;12376:1;12373;12366:12;12328:52;-1:-1:-1;12399:16:1;;12237:184;-1:-1:-1;12237:184:1:o;13132:138::-;13211:13;;13233:31;13211:13;13233:31;:::i;:::-;13132:138;;;:::o;13275:251::-;13345:6;13398:2;13386:9;13377:7;13373:23;13369:32;13366:52;;;13414:1;13411;13404:12;13366:52;13446:9;13440:16;13465:31;13490:5;13465:31;:::i;13531:192::-;13610:13;;13663:34;13652:46;;13642:57;;13632:85;;13713:1;13710;13703:12;13728:166;13806:13;;13859:2;13848:21;;;13838:32;;13828:60;;13884:1;13881;13874:12;13899:1421;13985:5;14038:3;14031:4;14023:6;14019:17;14015:27;14005:55;;14056:1;14053;14046:12;14005:55;14085:6;14079:13;14111:4;14134:18;14171:2;14167;14164:10;14161:36;;;14177:18;;:::i;:::-;14217:36;14249:2;14244;14241:1;14237:10;14233:19;14217:36;:::i;:::-;14287:15;;;14373:1;14369:10;;;;14357:23;;14353:32;;;14318:12;;;;14397:15;;;14394:35;;;14425:1;14422;14415:12;14394:35;14461:2;14453:6;14449:15;14473:818;14489:6;14484:3;14481:15;14473:818;;;14555:4;14594:2;14588:3;14583;14579:13;14575:22;14572:112;;;14638:1;14667:2;14663;14656:14;14572:112;14707:2;14736:9;;14776:15;;;;14810:18;;;14830:22;;;14807:46;14804:72;;;14856:18;;:::i;:::-;14900:10;14896:2;14889:22;14945:3;14939:10;14931:6;14924:26;14987:43;15026:2;15021:3;15017:12;14987:43;:::i;:::-;14982:2;14974:6;14970:15;14963:68;15068:42;15106:2;15101:3;15097:12;15068:42;:::i;:::-;15063:2;15055:6;15051:15;15044:67;15134:2;15124:12;;15173:43;15212:2;15207:3;15203:12;15173:43;:::i;:::-;15156:15;;;15149:68;;;;-1:-1:-1;15230:19:1;;15269:12;;;;14515:4;14506:14;14473:818;;;-1:-1:-1;15309:5:1;13899:1421;-1:-1:-1;;;;;;;13899:1421:1:o;15325:672::-;15385:5;15438:3;15431:4;15423:6;15419:17;15415:27;15405:55;;15456:1;15453;15446:12;15405:55;15489:2;15483:9;15531:2;15523:6;15519:15;15600:6;15588:10;15585:22;15564:18;15552:10;15549:34;15546:62;15543:88;;;15611:18;;:::i;:::-;15647:2;15640:22;15682:6;15723:2;15711:15;;15738;;;15735:35;;;15766:1;15763;15756:12;15735:35;15790:6;15805:162;15821:6;15816:3;15813:15;15805:162;;;15889:33;15918:3;15889:33;:::i;:::-;15877:46;;15952:4;15943:14;;;;15838;15805:162;;;-1:-1:-1;15985:6:1;;15325:672;-1:-1:-1;;;;;15325:672:1:o;16002:1301::-;16110:6;16163:2;16151:9;16142:7;16138:23;16134:32;16131:52;;;16179:1;16176;16169:12;16131:52;16212:9;16206:16;16241:18;16282:2;16274:6;16271:14;16268:34;;;16298:1;16295;16288:12;16268:34;16321:22;;;;16377:6;16359:16;;;16355:29;16352:49;;;16397:1;16394;16387:12;16352:49;16423:22;;:::i;:::-;16468:33;16498:2;16468:33;:::i;:::-;16461:5;16454:48;16548:2;16544;16540:11;16534:18;16529:2;16522:5;16518:14;16511:42;16592:2;16588;16584:11;16578:18;16621:2;16611:8;16608:16;16605:36;;;16637:1;16634;16627:12;16605:36;16673:88;16753:7;16742:8;16738:2;16734:17;16673:88;:::i;:::-;16668:2;16661:5;16657:14;16650:112;;16801:2;16797;16793:11;16787:18;16830:2;16820:8;16817:16;16814:36;;;16846:1;16843;16836:12;16814:36;16882:88;16962:7;16951:8;16947:2;16943:17;16882:88;:::i;:::-;16877:2;16870:5;16866:14;16859:112;;17010:3;17006:2;17002:12;16996:19;17040:2;17030:8;17027:16;17024:36;;;17056:1;17053;17046:12;17024:36;17093:88;17173:7;17162:8;17158:2;17154:17;17093:88;:::i;:::-;17087:3;17080:5;17076:15;17069:113;;17215:57;17264:7;17258:3;17254:2;17250:12;17215:57;:::i;:::-;17209:3;17198:15;;17191:82;17202:5;16002:1301;-1:-1:-1;;;;;16002:1301:1:o;18955:208::-;19025:6;19078:2;19066:9;19057:7;19053:23;19049:32;19046:52;;;19094:1;19091;19084:12;19046:52;19117:40;19147:9;19117:40;:::i;19168:195::-;19207:3;19238:66;19231:5;19228:77;19225:103;;19308:18;;:::i;:::-;-1:-1:-1;19355:1:1;19344:13;;19168:195::o;20674:175::-;20752:13;;20805:18;20794:30;;20784:41;;20774:69;;20839:1;20836;20829:12;20854:636;20955:6;21008:2;20996:9;20987:7;20983:23;20979:32;20976:52;;;21024:1;21021;21014:12;20976:52;21057:2;21051:9;21099:2;21091:6;21087:15;21168:6;21156:10;21153:22;21132:18;21120:10;21117:34;21114:62;21111:88;;;21179:18;;:::i;:::-;21215:2;21208:22;21254:40;21284:9;21254:40;:::i;:::-;21246:6;21239:56;21328:48;21372:2;21361:9;21357:18;21328:48;:::i;:::-;21323:2;21315:6;21311:15;21304:73;21410:48;21454:2;21443:9;21439:18;21410:48;:::i;:::-;21405:2;21393:15;;21386:73;21397:6;20854:636;-1:-1:-1;;;20854:636:1:o;22246:250::-;22331:1;22341:113;22355:6;22352:1;22349:13;22341:113;;;22431:11;;;22425:18;22412:11;;;22405:39;22377:2;22370:10;22341:113;;;-1:-1:-1;;22488:1:1;22470:16;;22463:27;22246:250::o;22501:287::-;22630:3;22668:6;22662:13;22684:66;22743:6;22738:3;22731:4;22723:6;22719:17;22684:66;:::i;:::-;22766:16;;;;;22501:287;-1:-1:-1;;22501:287:1:o;22793:245::-;22860:6;22913:2;22901:9;22892:7;22888:23;22884:32;22881:52;;;22929:1;22926;22919:12;22881:52;22961:9;22955:16;22980:28;23002:5;22980:28;:::i;24219:455::-;24368:2;24357:9;24350:21;24331:4;24400:6;24394:13;24443:6;24438:2;24427:9;24423:18;24416:34;24459:79;24531:6;24526:2;24515:9;24511:18;24506:2;24498:6;24494:15;24459:79;:::i;:::-;24590:2;24578:15;24595:66;24574:88;24559:104;;;;24665:2;24555:113;;24219:455;-1:-1:-1;;24219:455:1:o
Swarm Source
ipfs://bdc4a560a633ac5b2164af384022d2f11c5e07eac8e8d767d5283a718ff7dd43
Loading...
Loading
Loading...
Loading
Loading...
Loading
Net Worth in USD
$0.00
Net Worth in FRAX
0
Multichain Portfolio | 35 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.