Source Code
Latest 1 from a total of 1 transactions
| Transaction Hash |
|
Block
|
From
|
To
|
|||||
|---|---|---|---|---|---|---|---|---|---|
| Initialize | 3331003 | 654 days ago | IN | 0 FRAX | 0.00000243 |
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
6080604052601d805460ff1916905534801561001a57600080fd5b50600080546001600160a01b0319163390811782556040805192835260208301919091527fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c910160405180910390a16001600255613b278061007d6000396000f3fe608060405234801561001057600080fd5b50600436106103825760003560e01c8063819abfcd116101de578063c8f33c911161010f578063f0657ab6116100ad578063f868139b1161007c578063f868139b14610794578063fc939bb1146107a7578063fdda6ea3146107af578063fff6cae9146107c257600080fd5b8063f0657ab614610766578063f21b7235146103c2578063f43ae1c71461076e578063f5d812cb1461078157600080fd5b8063e172cf21116100e9578063e172cf211461072e578063e9218ff614610737578063ebe2b12b1461074a578063ee73e0461461075357600080fd5b8063c8f33c91146106ef578063d15166ff146106f8578063d96658d91461071b57600080fd5b80639f8a835a1161017c578063ad1148cb11610156578063ad1148cb146106bf578063bdacb303146106cc578063c0f456bd146106df578063c2c4c5c1146106e757600080fd5b80639f8a835a146106835780639faf3c6b14610696578063a875f4721461069f57600080fd5b806391519bda116101b857806391519bda1461062a578063941d9f651461063d578063948e25a21461065057806399bf71091461066357600080fd5b8063819abfcd146105fb5780638980f11f146106045780638da5cb5b1461061757600080fd5b806350fe98ac116102b85780636869f42f1161025657806374ea0b981161023057806374ea0b98146105c55780637873fae6146105d857806379ba5097146105eb5780637c262871146105f357600080fd5b80636869f42f1461058c5780636999ac931461059457806373f22f741461059d57600080fd5b806354e04d151161029257806354e04d151461054857806356d9fff3146105515780635762215614610559578063681b5ffa1461056c57600080fd5b806350fe98ac14610500578063525456d21461052057806353a47bb71461053557600080fd5b806319ff52fd116103255780633c6b16ab116102ff5780633c6b16ab146104a757806342c92f6e146104ba57806345ff83cb146104cd5780634bc66f32146104ed57600080fd5b806319ff52fd1461044e5780632f9b12f81461046157806331ca208c1461048457600080fd5b806314b305371161036157806314b30537146103d557806314b64f7c146104085780631627540c1461043357806319aec6d21461044657600080fd5b80628cc2621461038757806303d8477f146103ad578063054d2d1e146103c2575b600080fd5b61039a6103953660046132e3565b6107ca565b6040519081526020015b60405180910390f35b6103c06103bb366004613300565b6109fa565b005b6103c06103d03660046132e3565b610f2f565b6103f86103e33660046132e3565b60186020526000908152604090205460ff1681565b60405190151581526020016103a4565b60085461041b906001600160a01b031681565b6040516001600160a01b0390911681526020016103a4565b6103c06104413660046132e3565b611005565b61039a6110af565b60055461041b906001600160a01b031681565b6103f861046f3660046132e3565b600d6020526000908152604090205460ff1681565b6103f86104923660046132e3565b601c6020526000908152604090205460ff1681565b6103c06104b5366004613322565b6110c6565b6103c06104c83660046132e3565b6111e9565b61039a6104db3660046132e3565b60196020526000908152604090205481565b600b5461041b906001600160a01b031681565b61039a61050e3660046132e3565b60156020526000908152604090205481565b61052861128d565b6040516103a4919061333b565b60015461041b906001600160a01b031681565b61039a60135481565b61039a6112ef565b61041b610567366004613322565b611306565b61039a61057a3660046132e3565b601a6020526000908152604090205481565b61039a611330565b61039a60105481565b6105b06105ab3660046132e3565b611391565b604080519283526020830191909152016103a4565b6103c06105d3366004613322565b6113d6565b60035461041b906001600160a01b031681565b6103c06114b2565b61039a611580565b61039a60165481565b6103c0610612366004613388565b61170c565b60005461041b906001600160a01b031681565b6103c06106383660046133c2565b6117c7565b6103c061064b3660046132e3565b61183b565b6103c061065e3660046133f2565b6118df565b6106766106713660046132e3565b61196d565b6040516103a4919061340f565b6103c06106913660046132e3565b612311565b61039a60175481565b61039a6106ad3660046132e3565b60146020526000908152604090205481565b601d546103f89060ff1681565b6103c06106da3660046132e3565b61231a565b600c5461039a565b6103c06123b1565b61039a600f5481565b6103f86107063660046132e3565b60126020526000908152604090205460ff1681565b61039a6107293660046132e3565b6123bc565b61039a60115481565b60095461041b906001600160a01b031681565b61039a600e5481565b60045461041b906001600160a01b031681565b61039a612689565b600a5461041b906001600160a01b031681565b60065461041b906001600160a01b031681565b60075461041b906001600160a01b031681565b61039a6129e3565b6103c06107bd366004613532565b612a13565b6103c0612c2b565b6001600160a01b03811660009081526018602052604081205460ff166107f257506000919050565b6000806107fe84611391565b9092509050620f424060008390036108a3576001600160a01b0385166000908152601b6020526040902054821161083a57506000949350505050565b6001600160a01b0385166000908152601b602052604081205461085d9084613604565b6001600160a01b0387166000908152601b6020526040812054919250906108849042613604565b90508061089483620f424061361d565b61089e9190613634565b925050505b6001600160a01b038516600090815260196020526040812054808511156108cc5780915061096c565b60026108d8828761366f565b6108e29190613634565b6001600160a01b03881660009081526015602052604081205491935090610914620f4240670de0b6b3a764000061361d565b6001600160a01b038a166000908152601460205260409020548690610937611330565b6109419190613604565b61094b908661361d565b610955919061361d565b61095f9190613634565b610969919061366f565b50505b6001600160a01b03871660009081526015602052604090205461099a620f4240670de0b6b3a764000061361d565b6001600160a01b03891660009081526014602052604090205485906109bd611330565b6109c79190613604565b6109d1908661361d565b6109db919061361d565b6109e59190613634565b6109ef919061366f565b979650505050505050565b6000546001600160a01b03163314801590610a205750600b546001600160a01b03163314155b15610a57576040517ffee4291a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000610a6660208301836132e3565b6001600160a01b031603610ac15760405162461bcd60e51b815260206004820152601560248201527f7665465853206d757374206e6f7420626520307830000000000000000000000060448201526064015b60405180910390fd5b6000610ad360408301602084016132e3565b6001600160a01b031603610b295760405162461bcd60e51b815260206004820152601a60248201527f76654658535574696c73206d757374206e6f74206265203078300000000000006044820152606401610ab8565b6000610b3b60608301604084016132e3565b6001600160a01b031614610b915760405162461bcd60e51b815260206004820152601960248201527f43616e6e6f742061646420465049534c6f636b657220796574000000000000006044820152606401610ab8565b6000610ba360808301606084016132e3565b6001600160a01b031614610bf95760405162461bcd60e51b815260206004820152601e60248201527f43616e6e6f742061646420465049534c6f636b65725574696c732079657400006044820152606401610ab8565b6000610c0b60a08301608084016132e3565b6001600160a01b031614610c615760405162461bcd60e51b815260206004820152601660248201527f43616e6e6f7420616464204c31566546585320796574000000000000000000006044820152606401610ab8565b6000610c7360c0830160a084016132e3565b6001600160a01b031614610cef5760405162461bcd60e51b815260206004820152602760248201527f43616e6e6f7420616464204c315665465853546f74616c537570706c794f726160448201527f636c6520796574000000000000000000000000000000000000000000000000006064820152608401610ab8565b610cfc60208201826132e3565b600580547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0392909216919091179055610d4460408201602083016132e3565b600680547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b03929092169190911790556000610d8e60608301604084016132e3565b6001600160a01b031614158015610dbe57506000610db260808301606084016132e3565b6001600160a01b031614155b15610e5457610dd360608201604083016132e3565b600380547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0392909216919091179055610e1b60808201606083016132e3565b600780547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b03929092169190911790555b6000610e6660a08301608084016132e3565b6001600160a01b031614158015610e9657506000610e8a60c0830160a084016132e3565b6001600160a01b031614155b15610f2c57610eab60a08201608083016132e3565b600480547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0392909216919091179055610ef360c0820160a083016132e3565b600880547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b03929092169190911790555b50565b6000546001600160a01b03163314801590610f555750600b546001600160a01b03163314155b15610f8c576040517ffee4291a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60405162461bcd60e51b815260206004820152602e60248201527f43616e6e6f74206164642f72656d6f7665206164646974696f6e616c2076654660448201527f585320736f7572636573207965740000000000000000000000000000000000006064820152608401610ab8565b60405180910390a150565b6000546001600160a01b03163314611049576040517f5fc483c500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0383169081179091556040519081527f906a1c6bd7e3091ea86693dd029a831c19049ce77f1dce2ce0bab1cacbabce2290602001610ffa565b60006011546010546110c1919061361d565b905090565b3360009081526012602052604090205460ff1661110f576040517fae582d4300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600954611127906001600160a01b0316333084612c4e565b61112f612c2b565b600e54421061114d576011546111459082613634565b60105561118f565b600042600e5461115d9190613604565b905060006010548261116f919061361d565b60115490915061117f828561366f565b6111899190613634565b60105550505b42600f8190556011546111a19161366f565b600e556111ac612689565b6017556010546040805183815260208101929092527f6c07ee05dcf262f13abf9d87b846ee789d2f90fe991d495acd7d7fc109ee1f559101610ffa565b6000546001600160a01b0316331480159061120f5750600b546001600160a01b03163314155b15611246576040517ffee4291a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001600160a01b0316600090815260126020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00811660ff90911615179055565b6060600c8054806020026020016040519081016040528092919081815260200182805480156112e557602002820191906000526020600020905b81546001600160a01b031681526001909101906020018083116112c7575b5050505050905090565b6000600e5442106113015750600e5490565b504290565b600c818154811061131657600080fd5b6000918252602090912001546001600160a01b0316905081565b6000601754600003611343575060135490565b601754601054600f546113546112ef565b61135e9190613604565b611368919061361d565b61137a90670de0b6b3a764000061361d565b6113849190613634565b6013546110c1919061366f565b600080600061139f846123bc565b6001600160a01b0385166000908152601a6020526040902054925090504282116113cc57600092506113d0565b8092505b50915091565b6000546001600160a01b031633148015906113fc5750600b546001600160a01b03163314155b15611433576040517ffee4291a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600e54158015906114465750600e544211155b1561147d576040517f350e95f600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60118190556040518181527fce653f06b9044b00e7d9d01b9b4228e84812092cb6a38371889bef19370d21f790602001610ffa565b6001546001600160a01b031633146114f6576040517fd74b334e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600054600154604080516001600160a01b0393841681529290911660208301527fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c910160405180910390a160018054600080547fffffffffffffffffffffffff00000000000000000000000000000000000000009081166001600160a01b03841617909155169055565b600060028054036115d35760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610ab8565b60028055601d5460ff1615611614576040517f6efa33c900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3361161e81612cdc565b336000908152601c602052604090205460ff1615611668576040517f70e5228400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b33600090815260156020526040902054915081156116f15733600081815260156020526040812055600a546116a9916001600160a01b039091169084612ee0565b600a54604080518481526001600160a01b03909216602083015233917f3998039806f6db7e5d83a5371638cc47dd2e9ae500d5d561d95ec6381f53e3cd910160405180910390a25b50336000908152601b60205260409020429055600160025590565b6000546001600160a01b031633148015906117325750600b546001600160a01b03163314155b15611769576040517ffee4291a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000546117819083906001600160a01b031683612ee0565b604080516001600160a01b0384168152602081018390527f55350610fe57096d8c0ffa30beede987326bccfcb0b4415804164d0dd50ce8b1910160405180910390a15050565b6000546001600160a01b031633148015906117ed5750600b546001600160a01b03163314155b15611824576040517ffee4291a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6010829055801561183757611837612c2b565b5050565b6000546001600160a01b031633148015906118615750600b546001600160a01b03163314155b15611898576040517ffee4291a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001600160a01b03166000908152601c6020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00811660ff90911615179055565b6000546001600160a01b031633148015906119055750600b546001600160a01b03163314155b1561193c576040517ffee4291a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b601d80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016911515919091179055565b6005546040517fb9ef08300000000000000000000000000000000000000000000000000000000081526001600160a01b03838116600483015260609260009291169063b9ef083090602401602060405180830381865afa1580156119d5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119f9919061396c565b6003546fffffffffffffffffffffffffffffffff9190911691506001600160a01b031615611ac7576003546040517fb9ef08300000000000000000000000000000000000000000000000000000000081526001600160a01b0385811660048301529091169063b9ef083090602401602060405180830381865afa158015611a84573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611aa8919061396c565b611ac4906fffffffffffffffffffffffffffffffff168261366f565b90505b6004546001600160a01b031615801590611aeb57506008546001600160a01b031615155b15611afe57611afb60018261366f565b90505b60005b600c54811015611be8576000600c8281548110611b2057611b20613682565b6000918252602090912001546001600160a01b031690508015611bdf576040517fb9ef08300000000000000000000000000000000000000000000000000000000081526001600160a01b03868116600483015282169063b9ef083090602401602060405180830381865afa158015611b9c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611bc0919061396c565b611bdc906fffffffffffffffffffffffffffffffff168461366f565b92505b50600101611b01565b506000808267ffffffffffffffff811115611c0557611c0561348b565b604051908082528060200260200182016040528015611c7557816020015b6040805160808101825260008082526020808301829052928201819052606082015282527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff909201910181611c235790505b506006546040517f3c5933120000000000000000000000000000000000000000000000000000000081526001600160a01b03888116600483015292935060009290911690633c59331290602401600060405180830381865afa158015611cdf573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052611d259190810190613889565b60600151905060005b8151811015611d88576000828281518110611d4b57611d4b613682565b6020026020010151905080848681518110611d6857611d68613682565b602002602001018190525084611d7d90613987565b945050600101611d2e565b50506003546001600160a01b031615611f21576007546040517f3c5933120000000000000000000000000000000000000000000000000000000081526001600160a01b0387811660048301526000921690633c59331290602401600060405180830381865afa158015611dff573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052611e459190810190613889565b60600151905060005b8151811015611f1e576000828281518110611e6b57611e6b613682565b602002602001015190504281606001516fffffffffffffffffffffffffffffffff161115611f155760405180608001604052808260000151815260200182602001516fffffffffffffffffffffffffffffffff1681526020018260400151600f0b815260200182606001516fffffffffffffffffffffffffffffffff16815250848681518110611efd57611efd613682565b602002602001018190525084611f1290613987565b94505b50600101611e4e565b50505b6004546001600160a01b031615801590611f4557506008546001600160a01b031615155b1561207757600480546040517fcbf9fe5f0000000000000000000000000000000000000000000000000000000081526001600160a01b03888116938201939093526000929091169063cbf9fe5f90602401606060405180830381865afa158015611fb3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611fd791906139d7565b905042816020015167ffffffffffffffff1611156120755760405180608001604052806000815260200160006fffffffffffffffffffffffffffffffff1681526020018260000151600f0b8152602001826020015167ffffffffffffffff166fffffffffffffffffffffffffffffffff1681525082848151811061205d5761205d613682565b60200260200101819052508261207290613987565b92505b505b60005b600c54811015612230576000600c828154811061209957612099613682565b6000918252602090912001546001600160a01b031690508015612227576000816001600160a01b03166366d6bff96040518163ffffffff1660e01b8152600401602060405180830381865afa1580156120f6573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061211a91906136da565b6040517f3c5933120000000000000000000000000000000000000000000000000000000081526001600160a01b038a811660048301529190911690633c59331290602401600060405180830381865afa15801561217b573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526121c19190810190613889565b60600151905060005b81518110156122245760008282815181106121e7576121e7613682565b602002602001015190508086888151811061220457612204613682565b60200260200101819052508661221990613987565b9650506001016121ca565b50505b5060010161207a565b508167ffffffffffffffff81111561224a5761224a61348b565b6040519080825280602002602001820160405280156122ba57816020015b6040805160808101825260008082526020808301829052928201819052606082015282527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9092019101816122685790505b50935060005b8451811015612308578181815181106122db576122db613682565b60200260200101518582815181106122f5576122f5613682565b60209081029190910101526001016122c0565b50505050919050565b610f2c81612cdc565b6000546001600160a01b031633148015906123405750600b546001600160a01b03163314155b15612377576040517ffee4291a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600b80547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0392909216919091179055565b6123ba33612cdc565b565b6005546040517f70a082310000000000000000000000000000000000000000000000000000000081526001600160a01b03838116600483015260009216906370a0823190602401602060405180830381865afa158015612420573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061244491906136b1565b6003549091506001600160a01b0316156124ec576003546040517f70a082310000000000000000000000000000000000000000000000000000000081526001600160a01b038481166004830152909116906370a0823190602401602060405180830381865afa1580156124bb573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124df91906136b1565b6124e9908261366f565b90505b6004546001600160a01b03161580159061251057506008546001600160a01b031615155b156125ab57600480546040517f70a082310000000000000000000000000000000000000000000000000000000081526001600160a01b03858116938201939093529116906370a0823190602401602060405180830381865afa15801561257a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061259e91906136b1565b6125a8908261366f565b90505b60005b600c54811015612683576000600c82815481106125cd576125cd613682565b6000918252602090912001546001600160a01b03169050801561267a576040517f70a082310000000000000000000000000000000000000000000000000000000081526001600160a01b0385811660048301528216906370a0823190602401602060405180830381865afa158015612649573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061266d91906136b1565b612677908461366f565b92505b506001016125ae565b50919050565b600554604080517f18160ddd00000000000000000000000000000000000000000000000000000000815290516000926001600160a01b0316916318160ddd9160048083019260209291908290030181865afa1580156126ec573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061271091906136b1565b6003549091506001600160a01b0316156127a857600360009054906101000a90046001600160a01b03166001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612777573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061279b91906136b1565b6127a5908261366f565b90505b6004546001600160a01b0316158015906127cc57506008546001600160a01b031615155b1561285557600860009054906101000a90046001600160a01b03166001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612824573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061284891906136b1565b612852908261366f565b90505b60005b600c5481101561290c576000600c828154811061287757612877613682565b6000918252602090912001546001600160a01b03169050801561290357806001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156128d2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128f691906136b1565b612900908461366f565b92505b50600101612858565b5090565b600c548110156129a157816001600160a01b0316600c828154811061293757612937613682565b6000918252602090912001546001600160a01b031603612999576000600c828154811061296657612966613682565b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b031602179055506129a1565b600101612910565b506129aa612c2b565b6040516001600160a01b03821681527ff3517f912cde760e82811897047177df419c7aa16326d5710e6b425a8a7d103590602001610ffa565b60006017546000036129f55750600090565b601754620f4240601654612a09919061361d565b6110c19190613634565b6001600160a01b0382161580612a335750600a546001600160a01b031615155b15612a6a576040517fd08e7ac200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080546001600160a01b038681167fffffffffffffffffffffffff000000000000000000000000000000000000000092831617909255600a805485841690831681179091556009805483169091179055600b8054868416908316179055825160058054831691841691909117905560208301516006805490921690831617905560408201511615801590612b0b575060608101516001600160a01b031615155b15612b5f576040810151600380546001600160a01b039283167fffffffffffffffffffffffff0000000000000000000000000000000000000000918216179091556060830151600780549190931691161790555b60808101516001600160a01b031615801590612b87575060a08101516001600160a01b031615155b15612bdb576080810151600480546001600160a01b039283167fffffffffffffffffffffffff00000000000000000000000000000000000000009182161790915560a0830151600880549190931691161790555b505042600f55506001600160a01b0316600090815260126020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905562093a80601155565b612c33611330565b601355612c3e612689565b601755612c496112ef565b600f55565b604080516001600160a01b0385811660248301528416604482015260648082018490528251808303909101815260849091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f23b872dd00000000000000000000000000000000000000000000000000000000179052612cd6908590613011565b50505050565b612ce4612c2b565b612ced816130fb565b6001600160a01b03811660009081526019602052604081205490612d10836123bc565b6001600160a01b0384166000908152601960205260408120829055909150612d378461196d565b905060008082511115612d665781600081518110612d5757612d57613682565b60200260200101516060015190505b600182511115612df05760005b8251811015612dee57816fffffffffffffffffffffffffffffffff16838281518110612da157612da1613682565b6020026020010151606001516fffffffffffffffffffffffffffffffff161015612de657828181518110612dd757612dd7613682565b60200260200101516060015191505b600101612d73565b505b6001600160a01b0385166000908152601a602052604090206fffffffffffffffffffffffffffffffff82169055838310612e49576000612e308585613604565b905080601654612e40919061366f565b60165550612e6a565b6000612e558486613604565b905080601654612e659190613604565b601655505b6001600160a01b03851660009081526018602052604090205460ff16612ed9576001600160a01b038516600090815260186020908152604080832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055601b90915290204290555b5050505050565b604080516001600160a01b038481166024830152604480830185905283518084039091018152606490920183526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb000000000000000000000000000000000000000000000000000000001790529151600092839290871691612f6a9190613a67565b6000604051808303816000865af19150503d8060008114612fa7576040519150601f19603f3d011682016040523d82523d6000602084013e612fac565b606091505b5091509150811580612fda5750805115801590612fda575080806020019051810190612fd89190613a83565b155b15612ed9576040517f19a9708500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000613066826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166131449092919063ffffffff16565b8051909150156130f657808060200190518101906130849190613a83565b6130f65760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610ab8565b505050565b6001600160a01b03811615610f2c576000613115826107ca565b6001600160a01b0383166000908152601560209081526040808320939093556013546014909152919020555050565b6060613153848460008561315d565b90505b9392505050565b6060824710156131d55760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610ab8565b6001600160a01b0385163b61322c5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610ab8565b600080866001600160a01b031685876040516132489190613a67565b60006040518083038185875af1925050503d8060008114613285576040519150601f19603f3d011682016040523d82523d6000602084013e61328a565b606091505b50915091506109ef828286606083156132a4575081613156565b8251156132b45782518084602001fd5b8160405162461bcd60e51b8152600401610ab89190613aa0565b6001600160a01b0381168114610f2c57600080fd5b6000602082840312156132f557600080fd5b8135613156816132ce565b600060c0828403121561331257600080fd5b8260c08301111561268357600080fd5b60006020828403121561333457600080fd5b5035919050565b6020808252825182820181905260009190848201906040850190845b8181101561337c5783516001600160a01b031683529284019291840191600101613357565b50909695505050505050565b6000806040838503121561339b57600080fd5b82356133a6816132ce565b946020939093013593505050565b8015158114610f2c57600080fd5b600080604083850312156133d557600080fd5b8235915060208301356133e7816133b4565b809150509250929050565b60006020828403121561340457600080fd5b8135613156816133b4565b602080825282518282018190526000919060409081850190868401855b8281101561347e57815180518552868101516fffffffffffffffffffffffffffffffff9081168887015286820151600f0b8787015260609182015116908501526080909301929085019060010161342c565b5091979650505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60405160c0810167ffffffffffffffff811182821017156134dd576134dd61348b565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561352a5761352a61348b565b604052919050565b60008060008061012080868803121561354a57600080fd5b8535613555816132ce565b9450602086810135613566816132ce565b94506040870135613576816132ce565b9350607f8701881361358757600080fd5b61358f6134ba565b9187019180898411156135a157600080fd5b606089015b848110156135c65780356135b9816132ce565b83529183019183016135a6565b50969995985093965050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b81810381811115613617576136176135d5565b92915050565b8082028115828204841417613617576136176135d5565b60008261366a577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b80820180821115613617576136176135d5565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6000602082840312156136c357600080fd5b5051919050565b80516136d5816132ce565b919050565b6000602082840312156136ec57600080fd5b8151613156816132ce565b80516fffffffffffffffffffffffffffffffff811681146136d557600080fd5b8051600f81900b81146136d557600080fd5b600082601f83011261373a57600080fd5b8151602067ffffffffffffffff808311156137575761375761348b565b613765828460051b016134e3565b83815260079390931b8501820192828101908785111561378457600080fd5b8387015b8581101561380857608080828b0312156137a25760008081fd5b604080519182019186831181841017156137be576137be61348b565b828252835181526137d08885016136f7565b888201526137df828501613717565b82820152606092506137f28385016136f7565b9281019290925250835291840191608001613788565b50979650505050505050565b600082601f83011261382557600080fd5b6040516060810181811067ffffffffffffffff821117156138485761384861348b565b60405280606084018581111561385d57600080fd5b845b8181101561387e5761387081613717565b83526020928301920161385f565b509195945050505050565b60006020828403121561389b57600080fd5b815167ffffffffffffffff808211156138b357600080fd5b9083019061010082860312156138c857600080fd5b6138d06134ba565b6138d9836136ca565b8152602083015160208201526040830151828111156138f757600080fd5b61390387828601613729565b60408301525060608301518281111561391b57600080fd5b61392787828601613729565b60608301525060808301518281111561393f57600080fd5b61394b87828601613729565b60808301525061395e8660a08501613814565b60a082015295945050505050565b60006020828403121561397e57600080fd5b613156826136f7565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036139b8576139b86135d5565b5060010190565b805167ffffffffffffffff811681146136d557600080fd5b6000606082840312156139e957600080fd5b6040516060810181811067ffffffffffffffff82111715613a0c57613a0c61348b565b604052613a18836136f7565b8152613a26602084016139bf565b6020820152613a37604084016139bf565b60408201529392505050565b60005b83811015613a5e578181015183820152602001613a46565b50506000910152565b60008251613a79818460208701613a43565b9190910192915050565b600060208284031215613a9557600080fd5b8151613156816133b4565b6020815260008251806020840152613abf816040850160208701613a43565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea2646970667358221220b1d4074c9f3a0a0d84118d39446d8809008fea2a9d56a84706ea49f250cdaa1664736f6c63430008170033
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106103825760003560e01c8063819abfcd116101de578063c8f33c911161010f578063f0657ab6116100ad578063f868139b1161007c578063f868139b14610794578063fc939bb1146107a7578063fdda6ea3146107af578063fff6cae9146107c257600080fd5b8063f0657ab614610766578063f21b7235146103c2578063f43ae1c71461076e578063f5d812cb1461078157600080fd5b8063e172cf21116100e9578063e172cf211461072e578063e9218ff614610737578063ebe2b12b1461074a578063ee73e0461461075357600080fd5b8063c8f33c91146106ef578063d15166ff146106f8578063d96658d91461071b57600080fd5b80639f8a835a1161017c578063ad1148cb11610156578063ad1148cb146106bf578063bdacb303146106cc578063c0f456bd146106df578063c2c4c5c1146106e757600080fd5b80639f8a835a146106835780639faf3c6b14610696578063a875f4721461069f57600080fd5b806391519bda116101b857806391519bda1461062a578063941d9f651461063d578063948e25a21461065057806399bf71091461066357600080fd5b8063819abfcd146105fb5780638980f11f146106045780638da5cb5b1461061757600080fd5b806350fe98ac116102b85780636869f42f1161025657806374ea0b981161023057806374ea0b98146105c55780637873fae6146105d857806379ba5097146105eb5780637c262871146105f357600080fd5b80636869f42f1461058c5780636999ac931461059457806373f22f741461059d57600080fd5b806354e04d151161029257806354e04d151461054857806356d9fff3146105515780635762215614610559578063681b5ffa1461056c57600080fd5b806350fe98ac14610500578063525456d21461052057806353a47bb71461053557600080fd5b806319ff52fd116103255780633c6b16ab116102ff5780633c6b16ab146104a757806342c92f6e146104ba57806345ff83cb146104cd5780634bc66f32146104ed57600080fd5b806319ff52fd1461044e5780632f9b12f81461046157806331ca208c1461048457600080fd5b806314b305371161036157806314b30537146103d557806314b64f7c146104085780631627540c1461043357806319aec6d21461044657600080fd5b80628cc2621461038757806303d8477f146103ad578063054d2d1e146103c2575b600080fd5b61039a6103953660046132e3565b6107ca565b6040519081526020015b60405180910390f35b6103c06103bb366004613300565b6109fa565b005b6103c06103d03660046132e3565b610f2f565b6103f86103e33660046132e3565b60186020526000908152604090205460ff1681565b60405190151581526020016103a4565b60085461041b906001600160a01b031681565b6040516001600160a01b0390911681526020016103a4565b6103c06104413660046132e3565b611005565b61039a6110af565b60055461041b906001600160a01b031681565b6103f861046f3660046132e3565b600d6020526000908152604090205460ff1681565b6103f86104923660046132e3565b601c6020526000908152604090205460ff1681565b6103c06104b5366004613322565b6110c6565b6103c06104c83660046132e3565b6111e9565b61039a6104db3660046132e3565b60196020526000908152604090205481565b600b5461041b906001600160a01b031681565b61039a61050e3660046132e3565b60156020526000908152604090205481565b61052861128d565b6040516103a4919061333b565b60015461041b906001600160a01b031681565b61039a60135481565b61039a6112ef565b61041b610567366004613322565b611306565b61039a61057a3660046132e3565b601a6020526000908152604090205481565b61039a611330565b61039a60105481565b6105b06105ab3660046132e3565b611391565b604080519283526020830191909152016103a4565b6103c06105d3366004613322565b6113d6565b60035461041b906001600160a01b031681565b6103c06114b2565b61039a611580565b61039a60165481565b6103c0610612366004613388565b61170c565b60005461041b906001600160a01b031681565b6103c06106383660046133c2565b6117c7565b6103c061064b3660046132e3565b61183b565b6103c061065e3660046133f2565b6118df565b6106766106713660046132e3565b61196d565b6040516103a4919061340f565b6103c06106913660046132e3565b612311565b61039a60175481565b61039a6106ad3660046132e3565b60146020526000908152604090205481565b601d546103f89060ff1681565b6103c06106da3660046132e3565b61231a565b600c5461039a565b6103c06123b1565b61039a600f5481565b6103f86107063660046132e3565b60126020526000908152604090205460ff1681565b61039a6107293660046132e3565b6123bc565b61039a60115481565b60095461041b906001600160a01b031681565b61039a600e5481565b60045461041b906001600160a01b031681565b61039a612689565b600a5461041b906001600160a01b031681565b60065461041b906001600160a01b031681565b60075461041b906001600160a01b031681565b61039a6129e3565b6103c06107bd366004613532565b612a13565b6103c0612c2b565b6001600160a01b03811660009081526018602052604081205460ff166107f257506000919050565b6000806107fe84611391565b9092509050620f424060008390036108a3576001600160a01b0385166000908152601b6020526040902054821161083a57506000949350505050565b6001600160a01b0385166000908152601b602052604081205461085d9084613604565b6001600160a01b0387166000908152601b6020526040812054919250906108849042613604565b90508061089483620f424061361d565b61089e9190613634565b925050505b6001600160a01b038516600090815260196020526040812054808511156108cc5780915061096c565b60026108d8828761366f565b6108e29190613634565b6001600160a01b03881660009081526015602052604081205491935090610914620f4240670de0b6b3a764000061361d565b6001600160a01b038a166000908152601460205260409020548690610937611330565b6109419190613604565b61094b908661361d565b610955919061361d565b61095f9190613634565b610969919061366f565b50505b6001600160a01b03871660009081526015602052604090205461099a620f4240670de0b6b3a764000061361d565b6001600160a01b03891660009081526014602052604090205485906109bd611330565b6109c79190613604565b6109d1908661361d565b6109db919061361d565b6109e59190613634565b6109ef919061366f565b979650505050505050565b6000546001600160a01b03163314801590610a205750600b546001600160a01b03163314155b15610a57576040517ffee4291a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000610a6660208301836132e3565b6001600160a01b031603610ac15760405162461bcd60e51b815260206004820152601560248201527f7665465853206d757374206e6f7420626520307830000000000000000000000060448201526064015b60405180910390fd5b6000610ad360408301602084016132e3565b6001600160a01b031603610b295760405162461bcd60e51b815260206004820152601a60248201527f76654658535574696c73206d757374206e6f74206265203078300000000000006044820152606401610ab8565b6000610b3b60608301604084016132e3565b6001600160a01b031614610b915760405162461bcd60e51b815260206004820152601960248201527f43616e6e6f742061646420465049534c6f636b657220796574000000000000006044820152606401610ab8565b6000610ba360808301606084016132e3565b6001600160a01b031614610bf95760405162461bcd60e51b815260206004820152601e60248201527f43616e6e6f742061646420465049534c6f636b65725574696c732079657400006044820152606401610ab8565b6000610c0b60a08301608084016132e3565b6001600160a01b031614610c615760405162461bcd60e51b815260206004820152601660248201527f43616e6e6f7420616464204c31566546585320796574000000000000000000006044820152606401610ab8565b6000610c7360c0830160a084016132e3565b6001600160a01b031614610cef5760405162461bcd60e51b815260206004820152602760248201527f43616e6e6f7420616464204c315665465853546f74616c537570706c794f726160448201527f636c6520796574000000000000000000000000000000000000000000000000006064820152608401610ab8565b610cfc60208201826132e3565b600580547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0392909216919091179055610d4460408201602083016132e3565b600680547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b03929092169190911790556000610d8e60608301604084016132e3565b6001600160a01b031614158015610dbe57506000610db260808301606084016132e3565b6001600160a01b031614155b15610e5457610dd360608201604083016132e3565b600380547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0392909216919091179055610e1b60808201606083016132e3565b600780547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b03929092169190911790555b6000610e6660a08301608084016132e3565b6001600160a01b031614158015610e9657506000610e8a60c0830160a084016132e3565b6001600160a01b031614155b15610f2c57610eab60a08201608083016132e3565b600480547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0392909216919091179055610ef360c0820160a083016132e3565b600880547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b03929092169190911790555b50565b6000546001600160a01b03163314801590610f555750600b546001600160a01b03163314155b15610f8c576040517ffee4291a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60405162461bcd60e51b815260206004820152602e60248201527f43616e6e6f74206164642f72656d6f7665206164646974696f6e616c2076654660448201527f585320736f7572636573207965740000000000000000000000000000000000006064820152608401610ab8565b60405180910390a150565b6000546001600160a01b03163314611049576040517f5fc483c500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0383169081179091556040519081527f906a1c6bd7e3091ea86693dd029a831c19049ce77f1dce2ce0bab1cacbabce2290602001610ffa565b60006011546010546110c1919061361d565b905090565b3360009081526012602052604090205460ff1661110f576040517fae582d4300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600954611127906001600160a01b0316333084612c4e565b61112f612c2b565b600e54421061114d576011546111459082613634565b60105561118f565b600042600e5461115d9190613604565b905060006010548261116f919061361d565b60115490915061117f828561366f565b6111899190613634565b60105550505b42600f8190556011546111a19161366f565b600e556111ac612689565b6017556010546040805183815260208101929092527f6c07ee05dcf262f13abf9d87b846ee789d2f90fe991d495acd7d7fc109ee1f559101610ffa565b6000546001600160a01b0316331480159061120f5750600b546001600160a01b03163314155b15611246576040517ffee4291a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001600160a01b0316600090815260126020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00811660ff90911615179055565b6060600c8054806020026020016040519081016040528092919081815260200182805480156112e557602002820191906000526020600020905b81546001600160a01b031681526001909101906020018083116112c7575b5050505050905090565b6000600e5442106113015750600e5490565b504290565b600c818154811061131657600080fd5b6000918252602090912001546001600160a01b0316905081565b6000601754600003611343575060135490565b601754601054600f546113546112ef565b61135e9190613604565b611368919061361d565b61137a90670de0b6b3a764000061361d565b6113849190613634565b6013546110c1919061366f565b600080600061139f846123bc565b6001600160a01b0385166000908152601a6020526040902054925090504282116113cc57600092506113d0565b8092505b50915091565b6000546001600160a01b031633148015906113fc5750600b546001600160a01b03163314155b15611433576040517ffee4291a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600e54158015906114465750600e544211155b1561147d576040517f350e95f600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60118190556040518181527fce653f06b9044b00e7d9d01b9b4228e84812092cb6a38371889bef19370d21f790602001610ffa565b6001546001600160a01b031633146114f6576040517fd74b334e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600054600154604080516001600160a01b0393841681529290911660208301527fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c910160405180910390a160018054600080547fffffffffffffffffffffffff00000000000000000000000000000000000000009081166001600160a01b03841617909155169055565b600060028054036115d35760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610ab8565b60028055601d5460ff1615611614576040517f6efa33c900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3361161e81612cdc565b336000908152601c602052604090205460ff1615611668576040517f70e5228400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b33600090815260156020526040902054915081156116f15733600081815260156020526040812055600a546116a9916001600160a01b039091169084612ee0565b600a54604080518481526001600160a01b03909216602083015233917f3998039806f6db7e5d83a5371638cc47dd2e9ae500d5d561d95ec6381f53e3cd910160405180910390a25b50336000908152601b60205260409020429055600160025590565b6000546001600160a01b031633148015906117325750600b546001600160a01b03163314155b15611769576040517ffee4291a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000546117819083906001600160a01b031683612ee0565b604080516001600160a01b0384168152602081018390527f55350610fe57096d8c0ffa30beede987326bccfcb0b4415804164d0dd50ce8b1910160405180910390a15050565b6000546001600160a01b031633148015906117ed5750600b546001600160a01b03163314155b15611824576040517ffee4291a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6010829055801561183757611837612c2b565b5050565b6000546001600160a01b031633148015906118615750600b546001600160a01b03163314155b15611898576040517ffee4291a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001600160a01b03166000908152601c6020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00811660ff90911615179055565b6000546001600160a01b031633148015906119055750600b546001600160a01b03163314155b1561193c576040517ffee4291a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b601d80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016911515919091179055565b6005546040517fb9ef08300000000000000000000000000000000000000000000000000000000081526001600160a01b03838116600483015260609260009291169063b9ef083090602401602060405180830381865afa1580156119d5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119f9919061396c565b6003546fffffffffffffffffffffffffffffffff9190911691506001600160a01b031615611ac7576003546040517fb9ef08300000000000000000000000000000000000000000000000000000000081526001600160a01b0385811660048301529091169063b9ef083090602401602060405180830381865afa158015611a84573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611aa8919061396c565b611ac4906fffffffffffffffffffffffffffffffff168261366f565b90505b6004546001600160a01b031615801590611aeb57506008546001600160a01b031615155b15611afe57611afb60018261366f565b90505b60005b600c54811015611be8576000600c8281548110611b2057611b20613682565b6000918252602090912001546001600160a01b031690508015611bdf576040517fb9ef08300000000000000000000000000000000000000000000000000000000081526001600160a01b03868116600483015282169063b9ef083090602401602060405180830381865afa158015611b9c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611bc0919061396c565b611bdc906fffffffffffffffffffffffffffffffff168461366f565b92505b50600101611b01565b506000808267ffffffffffffffff811115611c0557611c0561348b565b604051908082528060200260200182016040528015611c7557816020015b6040805160808101825260008082526020808301829052928201819052606082015282527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff909201910181611c235790505b506006546040517f3c5933120000000000000000000000000000000000000000000000000000000081526001600160a01b03888116600483015292935060009290911690633c59331290602401600060405180830381865afa158015611cdf573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052611d259190810190613889565b60600151905060005b8151811015611d88576000828281518110611d4b57611d4b613682565b6020026020010151905080848681518110611d6857611d68613682565b602002602001018190525084611d7d90613987565b945050600101611d2e565b50506003546001600160a01b031615611f21576007546040517f3c5933120000000000000000000000000000000000000000000000000000000081526001600160a01b0387811660048301526000921690633c59331290602401600060405180830381865afa158015611dff573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052611e459190810190613889565b60600151905060005b8151811015611f1e576000828281518110611e6b57611e6b613682565b602002602001015190504281606001516fffffffffffffffffffffffffffffffff161115611f155760405180608001604052808260000151815260200182602001516fffffffffffffffffffffffffffffffff1681526020018260400151600f0b815260200182606001516fffffffffffffffffffffffffffffffff16815250848681518110611efd57611efd613682565b602002602001018190525084611f1290613987565b94505b50600101611e4e565b50505b6004546001600160a01b031615801590611f4557506008546001600160a01b031615155b1561207757600480546040517fcbf9fe5f0000000000000000000000000000000000000000000000000000000081526001600160a01b03888116938201939093526000929091169063cbf9fe5f90602401606060405180830381865afa158015611fb3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611fd791906139d7565b905042816020015167ffffffffffffffff1611156120755760405180608001604052806000815260200160006fffffffffffffffffffffffffffffffff1681526020018260000151600f0b8152602001826020015167ffffffffffffffff166fffffffffffffffffffffffffffffffff1681525082848151811061205d5761205d613682565b60200260200101819052508261207290613987565b92505b505b60005b600c54811015612230576000600c828154811061209957612099613682565b6000918252602090912001546001600160a01b031690508015612227576000816001600160a01b03166366d6bff96040518163ffffffff1660e01b8152600401602060405180830381865afa1580156120f6573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061211a91906136da565b6040517f3c5933120000000000000000000000000000000000000000000000000000000081526001600160a01b038a811660048301529190911690633c59331290602401600060405180830381865afa15801561217b573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526121c19190810190613889565b60600151905060005b81518110156122245760008282815181106121e7576121e7613682565b602002602001015190508086888151811061220457612204613682565b60200260200101819052508661221990613987565b9650506001016121ca565b50505b5060010161207a565b508167ffffffffffffffff81111561224a5761224a61348b565b6040519080825280602002602001820160405280156122ba57816020015b6040805160808101825260008082526020808301829052928201819052606082015282527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9092019101816122685790505b50935060005b8451811015612308578181815181106122db576122db613682565b60200260200101518582815181106122f5576122f5613682565b60209081029190910101526001016122c0565b50505050919050565b610f2c81612cdc565b6000546001600160a01b031633148015906123405750600b546001600160a01b03163314155b15612377576040517ffee4291a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600b80547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0392909216919091179055565b6123ba33612cdc565b565b6005546040517f70a082310000000000000000000000000000000000000000000000000000000081526001600160a01b03838116600483015260009216906370a0823190602401602060405180830381865afa158015612420573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061244491906136b1565b6003549091506001600160a01b0316156124ec576003546040517f70a082310000000000000000000000000000000000000000000000000000000081526001600160a01b038481166004830152909116906370a0823190602401602060405180830381865afa1580156124bb573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124df91906136b1565b6124e9908261366f565b90505b6004546001600160a01b03161580159061251057506008546001600160a01b031615155b156125ab57600480546040517f70a082310000000000000000000000000000000000000000000000000000000081526001600160a01b03858116938201939093529116906370a0823190602401602060405180830381865afa15801561257a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061259e91906136b1565b6125a8908261366f565b90505b60005b600c54811015612683576000600c82815481106125cd576125cd613682565b6000918252602090912001546001600160a01b03169050801561267a576040517f70a082310000000000000000000000000000000000000000000000000000000081526001600160a01b0385811660048301528216906370a0823190602401602060405180830381865afa158015612649573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061266d91906136b1565b612677908461366f565b92505b506001016125ae565b50919050565b600554604080517f18160ddd00000000000000000000000000000000000000000000000000000000815290516000926001600160a01b0316916318160ddd9160048083019260209291908290030181865afa1580156126ec573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061271091906136b1565b6003549091506001600160a01b0316156127a857600360009054906101000a90046001600160a01b03166001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612777573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061279b91906136b1565b6127a5908261366f565b90505b6004546001600160a01b0316158015906127cc57506008546001600160a01b031615155b1561285557600860009054906101000a90046001600160a01b03166001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612824573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061284891906136b1565b612852908261366f565b90505b60005b600c5481101561290c576000600c828154811061287757612877613682565b6000918252602090912001546001600160a01b03169050801561290357806001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156128d2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128f691906136b1565b612900908461366f565b92505b50600101612858565b5090565b600c548110156129a157816001600160a01b0316600c828154811061293757612937613682565b6000918252602090912001546001600160a01b031603612999576000600c828154811061296657612966613682565b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b031602179055506129a1565b600101612910565b506129aa612c2b565b6040516001600160a01b03821681527ff3517f912cde760e82811897047177df419c7aa16326d5710e6b425a8a7d103590602001610ffa565b60006017546000036129f55750600090565b601754620f4240601654612a09919061361d565b6110c19190613634565b6001600160a01b0382161580612a335750600a546001600160a01b031615155b15612a6a576040517fd08e7ac200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080546001600160a01b038681167fffffffffffffffffffffffff000000000000000000000000000000000000000092831617909255600a805485841690831681179091556009805483169091179055600b8054868416908316179055825160058054831691841691909117905560208301516006805490921690831617905560408201511615801590612b0b575060608101516001600160a01b031615155b15612b5f576040810151600380546001600160a01b039283167fffffffffffffffffffffffff0000000000000000000000000000000000000000918216179091556060830151600780549190931691161790555b60808101516001600160a01b031615801590612b87575060a08101516001600160a01b031615155b15612bdb576080810151600480546001600160a01b039283167fffffffffffffffffffffffff00000000000000000000000000000000000000009182161790915560a0830151600880549190931691161790555b505042600f55506001600160a01b0316600090815260126020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905562093a80601155565b612c33611330565b601355612c3e612689565b601755612c496112ef565b600f55565b604080516001600160a01b0385811660248301528416604482015260648082018490528251808303909101815260849091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f23b872dd00000000000000000000000000000000000000000000000000000000179052612cd6908590613011565b50505050565b612ce4612c2b565b612ced816130fb565b6001600160a01b03811660009081526019602052604081205490612d10836123bc565b6001600160a01b0384166000908152601960205260408120829055909150612d378461196d565b905060008082511115612d665781600081518110612d5757612d57613682565b60200260200101516060015190505b600182511115612df05760005b8251811015612dee57816fffffffffffffffffffffffffffffffff16838281518110612da157612da1613682565b6020026020010151606001516fffffffffffffffffffffffffffffffff161015612de657828181518110612dd757612dd7613682565b60200260200101516060015191505b600101612d73565b505b6001600160a01b0385166000908152601a602052604090206fffffffffffffffffffffffffffffffff82169055838310612e49576000612e308585613604565b905080601654612e40919061366f565b60165550612e6a565b6000612e558486613604565b905080601654612e659190613604565b601655505b6001600160a01b03851660009081526018602052604090205460ff16612ed9576001600160a01b038516600090815260186020908152604080832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055601b90915290204290555b5050505050565b604080516001600160a01b038481166024830152604480830185905283518084039091018152606490920183526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb000000000000000000000000000000000000000000000000000000001790529151600092839290871691612f6a9190613a67565b6000604051808303816000865af19150503d8060008114612fa7576040519150601f19603f3d011682016040523d82523d6000602084013e612fac565b606091505b5091509150811580612fda5750805115801590612fda575080806020019051810190612fd89190613a83565b155b15612ed9576040517f19a9708500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000613066826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166131449092919063ffffffff16565b8051909150156130f657808060200190518101906130849190613a83565b6130f65760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610ab8565b505050565b6001600160a01b03811615610f2c576000613115826107ca565b6001600160a01b0383166000908152601560209081526040808320939093556013546014909152919020555050565b6060613153848460008561315d565b90505b9392505050565b6060824710156131d55760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610ab8565b6001600160a01b0385163b61322c5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610ab8565b600080866001600160a01b031685876040516132489190613a67565b60006040518083038185875af1925050503d8060008114613285576040519150601f19603f3d011682016040523d82523d6000602084013e61328a565b606091505b50915091506109ef828286606083156132a4575081613156565b8251156132b45782518084602001fd5b8160405162461bcd60e51b8152600401610ab89190613aa0565b6001600160a01b0381168114610f2c57600080fd5b6000602082840312156132f557600080fd5b8135613156816132ce565b600060c0828403121561331257600080fd5b8260c08301111561268357600080fd5b60006020828403121561333457600080fd5b5035919050565b6020808252825182820181905260009190848201906040850190845b8181101561337c5783516001600160a01b031683529284019291840191600101613357565b50909695505050505050565b6000806040838503121561339b57600080fd5b82356133a6816132ce565b946020939093013593505050565b8015158114610f2c57600080fd5b600080604083850312156133d557600080fd5b8235915060208301356133e7816133b4565b809150509250929050565b60006020828403121561340457600080fd5b8135613156816133b4565b602080825282518282018190526000919060409081850190868401855b8281101561347e57815180518552868101516fffffffffffffffffffffffffffffffff9081168887015286820151600f0b8787015260609182015116908501526080909301929085019060010161342c565b5091979650505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60405160c0810167ffffffffffffffff811182821017156134dd576134dd61348b565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561352a5761352a61348b565b604052919050565b60008060008061012080868803121561354a57600080fd5b8535613555816132ce565b9450602086810135613566816132ce565b94506040870135613576816132ce565b9350607f8701881361358757600080fd5b61358f6134ba565b9187019180898411156135a157600080fd5b606089015b848110156135c65780356135b9816132ce565b83529183019183016135a6565b50969995985093965050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b81810381811115613617576136176135d5565b92915050565b8082028115828204841417613617576136176135d5565b60008261366a577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b80820180821115613617576136176135d5565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6000602082840312156136c357600080fd5b5051919050565b80516136d5816132ce565b919050565b6000602082840312156136ec57600080fd5b8151613156816132ce565b80516fffffffffffffffffffffffffffffffff811681146136d557600080fd5b8051600f81900b81146136d557600080fd5b600082601f83011261373a57600080fd5b8151602067ffffffffffffffff808311156137575761375761348b565b613765828460051b016134e3565b83815260079390931b8501820192828101908785111561378457600080fd5b8387015b8581101561380857608080828b0312156137a25760008081fd5b604080519182019186831181841017156137be576137be61348b565b828252835181526137d08885016136f7565b888201526137df828501613717565b82820152606092506137f28385016136f7565b9281019290925250835291840191608001613788565b50979650505050505050565b600082601f83011261382557600080fd5b6040516060810181811067ffffffffffffffff821117156138485761384861348b565b60405280606084018581111561385d57600080fd5b845b8181101561387e5761387081613717565b83526020928301920161385f565b509195945050505050565b60006020828403121561389b57600080fd5b815167ffffffffffffffff808211156138b357600080fd5b9083019061010082860312156138c857600080fd5b6138d06134ba565b6138d9836136ca565b8152602083015160208201526040830151828111156138f757600080fd5b61390387828601613729565b60408301525060608301518281111561391b57600080fd5b61392787828601613729565b60608301525060808301518281111561393f57600080fd5b61394b87828601613729565b60808301525061395e8660a08501613814565b60a082015295945050505050565b60006020828403121561397e57600080fd5b613156826136f7565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036139b8576139b86135d5565b5060010190565b805167ffffffffffffffff811681146136d557600080fd5b6000606082840312156139e957600080fd5b6040516060810181811067ffffffffffffffff82111715613a0c57613a0c61348b565b604052613a18836136f7565b8152613a26602084016139bf565b6020820152613a37604084016139bf565b60408201529392505050565b60005b83811015613a5e578181015183820152602001613a46565b50506000910152565b60008251613a79818460208701613a43565b9190910192915050565b600060208284031215613a9557600080fd5b8151613156816133b4565b6020815260008251806020840152613abf816040850160208701613a43565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea2646970667358221220b1d4074c9f3a0a0d84118d39446d8809008fea2a9d56a84706ea49f250cdaa1664736f6c63430008170033
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;;;;;-1:-1:-1;;;;;155119:56:0;;;;;;-1:-1:-1;;;;;1254:55:1;;;1236:74;;1224:2;1209:18;155119:56:0;1057:259:1;100460:141:0;;;;;;:::i;:::-;;:::i;169309:123::-;;;:::i;154807:23::-;;;;;-1:-1:-1;;;;;154807:23:0;;;155697:47;;;;;;:::i;:::-;;;;;;;;;;;;;;;;157850:40;;;;;;:::i;:::-;;;;;;;;;;;;;;;;181841:1159;;;;;;:::i;:::-;;:::i;186531:158::-;;;;;;:::i;:::-;;:::i;157294:56::-;;;;;;:::i;:::-;;;;;;;;;;;;;;155465:30;;;;;-1:-1:-1;;;;;155465:30:0;;;156789:41;;;;;;:::i;:::-;;;;;;;;;;;;;;169539:134;;;:::i;:::-;;;;;;;:::i;100311:29::-;;;;;-1:-1:-1;;;;;100311:29:0;;;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::-;;;;;-1:-1:-1;;;;;154614:29:0;;;100609:354;;;:::i;180525:580::-;;;:::i;156972:38::-;;;;;;185418:306;;;;;;:::i;:::-;;:::i;100284:20::-;;;;;-1:-1:-1;;;;;100284:20:0;;;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;;;;;-1:-1:-1;;;;;155243:25:0;;;155875:27;;;;;;154731:23;;;;;-1:-1:-1;;;;;154731:23:0;;;163132:972;;;:::i;155381:34::-;;;;;-1:-1:-1;;;;;155381:34:0;;;154894:33;;;;;-1:-1:-1;;;;;154894:33:0;;;155002;;;;;-1:-1:-1;;;;;155002:33:0;;;161490:236;;;:::i;159692:1482::-;;;;;;:::i;:::-;;:::i;181159:560::-;;;:::i;165848:3335::-;-1:-1:-1;;;;;166085:27:0;;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;;-1:-1:-1;;;;;166786:29:0;;;;;;: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::-;-1:-1:-1;;;;;167237:29:0;;167196:20;167237:29;;;:19;:29;;;;;;167219:47;;:15;:47;:::i;:::-;-1:-1:-1;;;;;167389:29:0;;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;-1:-1:-1;;;;;167872:31:0;;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;:::-;-1:-1:-1;;;;;168843:16:0;;168622:25;168843:16;;;:6;:16;;;;;;168369:64;;-1:-1:-1;168622:25:0;168800:22;158040:3;168800:4;:22;:::i;:::-;-1:-1:-1;;;;;168706:31:0;;;;;;: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;-1:-1:-1;;;;;169158:16:0;;;;;;:6;:16;;;;;;169119:22;158040:3;169119:4;:22;:::i;:::-;-1:-1:-1;;;;;169046:31:0;;;;;;: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;;-1:-1:-1;;;;;158670:5:0;158656:10;:19;;;;:52;;-1:-1:-1;158693:15:0;;-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;:::-;-1:-1:-1::0;;;;;187085:29:0::1;::::0;187077:63:::1;;;::::0;-1:-1:-1;;;187077:63: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;:::-;-1:-1:-1::0;;;;;187159:29:0::1;::::0;187151:68:::1;;;::::0;-1:-1:-1;;;187151:68: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;:::-;-1:-1:-1::0;;;;;187238:29:0::1;;187230:67;;;::::0;-1:-1:-1;;;187230:67: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;:::-;-1:-1:-1::0;;;;;187316:29:0::1;;187308:72;;;::::0;-1:-1:-1;;;187308:72: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;:::-;-1:-1:-1::0;;;;;187399:29:0::1;;187391:64;;;::::0;-1:-1:-1;;;187391:64: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;:::-;-1:-1:-1::0;;;;;187474:29:0::1;;187466:81;;;::::0;-1:-1:-1;;;187466:81: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;-1:-1:-1::0;;;;;187597:35:0;;;::::1;::::0;;;::::1;::::0;;187672:15:::1;::::0;;;::::1;::::0;::::1;;:::i;:::-;187643:10;:45:::0;;;::::1;-1:-1:-1::0;;;;;187643:45:0;;;::::1;::::0;;;::::1;::::0;;-1:-1:-1;187730:15:0::1;::::0;;;;;::::1;;:::i;:::-;-1:-1:-1::0;;;;;187730:29:0::1;;;187729:64;;;;-1:-1:-1::0;187791:1:0::1;187764:15;::::0;;;;;::::1;;:::i;:::-;-1:-1:-1::0;;;;;187764:29:0::1;;;187729:64;187725:198;;;187835:15;::::0;;;;;::::1;;:::i;:::-;187810:10;:41:::0;;;::::1;-1:-1:-1::0;;;;;187810:41:0;;;::::1;::::0;;;::::1;::::0;;187895:15:::1;::::0;;;;;::::1;;:::i;:::-;187866:10;:45:::0;;;::::1;-1:-1:-1::0;;;;;187866:45:0;;;::::1;::::0;;;::::1;::::0;;187725:198:::1;188016:1;187989:15;::::0;;;;;::::1;;:::i;:::-;-1:-1:-1::0;;;;;187989:29:0::1;;;187988:66;;;;-1:-1:-1::0;188051:1:0::1;188024:15;::::0;;;;;::::1;;:::i;:::-;-1:-1:-1::0;;;;;188024:29:0::1;;;187988:66;187984:217;;;188090:15;::::0;;;;;::::1;;:::i;:::-;188071:7;:35:::0;;;::::1;-1:-1:-1::0;;;;;188071:35:0;;;::::1;::::0;;;::::1;::::0;;188173:15:::1;::::0;;;;;::::1;;:::i;:::-;188121:24;:68:::0;;;::::1;-1:-1:-1::0;;;;;188121:68:0;;;::::1;::::0;;;::::1;::::0;;187984:217:::1;186910:1298:::0;:::o;183313:895::-;158670:5;;-1:-1:-1;;;;;158670:5:0;158656:10;:19;;;;:52;;-1:-1:-1;158693:15:0;;-1:-1:-1;;;;;158693:15:0;158679:10;:29;;158656:52;158652:85;;;158717:20;;;;;;;;;;;;;;158652:85;183467:64:::1;::::0;-1:-1:-1;;;183467:64: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;;-1:-1:-1;;;;;101114:5:0;101100:10;:19;101096:43;;101128:11;;;;;;;;;;;;;;101096:43;100532:14:::1;:23:::0;;;::::1;-1:-1:-1::0;;;;;100532:23: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;;-1:-1:-1;;;;;182211:12:0;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;;-1:-1:-1;;;;;158670:5:0;158656:10;:19;;;;:52;;-1:-1:-1;158693:15:0;;-1:-1:-1;;;;;158693:15:0;158679:10;:29;;158656:52;158652:85;;;158717:20;;;;;;;;;;;;;;158652:85;-1:-1:-1;;;;;186651:30:0::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;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;169640:25:0;;;;;;;;;;;;;;;;;;;;;;;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;;-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;:::-;-1:-1:-1;;;;;164732:36:0;;;;;;: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;;-1:-1:-1;;;;;158670:5:0;158656:10;:19;;;;:52;;-1:-1:-1;158693:15:0;;-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;;-1:-1:-1;;;;;100782:14:0;100768:10;:28;100764:69;;100805:28;;;;;;;;;;;;;;100764:69;100862:5;;;100869:14;100849:35;;;-1:-1:-1;;;;;100862:5:0;;;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;;;;;;-1:-1:-1;;;;;100903:14:0;;100895:22;;;;100928:27;;;100609:354::o;180525:580::-;180673:15;73099:1;73697:7;;:19;73689:63;;;;-1:-1:-1;;;73689:63:0;;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;-1:-1:-1;;;;;180907:19:0;;::::3;::::0;180940:7;180879:27:::3;:69::i;:::-;181004:19;::::0;180968:56:::3;::::0;;18525:25:1;;;-1:-1:-1;;;;;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;;-1:-1:-1;;;;;158670:5:0;158656:10;:19;;;;:52;;-1:-1:-1;158693:15:0;;-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;;-1:-1:-1;;;;;185637:5:0::1;185644:12:::0;185594:27:::1;:63::i;:::-;185673:43;::::0;;-1:-1:-1;;;;;18845:55:1;;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;;-1:-1:-1;;;;;158670:5:0;158656:10;:19;;;;:52;;-1:-1:-1;158693:15:0;;-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;;-1:-1:-1;;;;;158670:5:0;158656:10;:19;;;;:52;;-1:-1:-1;158693:15:0;;-1:-1:-1;;;;;158693:15:0;158679:10;:29;;158656:52;158652:85;;;158717:20;;;;;;;;;;;;;;158652:85;-1:-1:-1;;;;;186371:18:0::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;;-1:-1:-1;;;;;158670:5:0;158656:10;:19;;;;:52;;-1:-1:-1;158693:15:0;;-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;;;;;-1:-1:-1;;;;;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;;;;;;170578:10:0;170570:33;170566:83;;170620:10;;:29;;;;;-1:-1:-1;;;;;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;;-1:-1:-1;;;;;170706:7:0;170698:30;;;;170697:85;;-1:-1:-1;170742:24:0;;-1:-1:-1;;;;;170742:24:0;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;;;;;171060:21:0;;-1:-1:-1;171100:21:0;;171096:165;;171207:38;;;;;-1:-1:-1;;;;;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;;;;;-1:-1:-1;;;;;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;;-1:-1:-1;;;;;172614:10:0;172606:33;172602:1321;;172795:10;;:44;;;;;-1:-1:-1;;;;;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;;-1:-1:-1;;;;;174017:7:0;174009:30;;;;174008:85;;-1:-1:-1;174053:24:0;;-1:-1:-1;;;;;174053:24:0;174045:47;;174008:85;174004:790;;;174197:7;;;:24;;;;;-1:-1:-1;;;;;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;;;;;175000:21:0;;-1:-1:-1;175040:21:0;;175036:1074;;175123:55;175231:7;-1:-1:-1;;;;;175220:30:0;;:32;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;175204:83;;;;;-1:-1:-1;;;;;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;;-1:-1:-1;;;;;158670:5:0;158656:10;:19;;;;:52;;-1:-1:-1;158693:15:0;;-1:-1:-1;;;;;158693:15:0;158679:10;:29;;158656:52;158652:85;;;158717:20;;;;;;;;;;;;;;158652:85;189019:15:::1;:30:::0;;;::::1;-1:-1:-1::0;;;;;189019:30: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;;;;;-1:-1:-1;;;;;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;;;;;;162253:10:0;162245:33;162241:78;;162292:10;;:27;;;;;-1:-1:-1;;;;;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;;-1:-1:-1;;;;;162430:7:0;162422:30;;;;162421:85;;-1:-1:-1;162466:24:0;;-1:-1:-1;;;;;162466:24:0;162458:47;;162421:85;162417:154;;;162535:7;;;:24;;;;;-1:-1:-1;;;;;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;;;;;162727:21:0;;-1:-1:-1;162767:21:0;;162763:110;;162821:36;;;;;-1:-1:-1;;;;;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;;-1:-1:-1;;;;;163356:5:0;;:17;;:19;;;;;;;;;;;;;;:5;:19;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;163446:10;;163341:34;;-1:-1:-1;;;;;;163446:10:0;163438:33;163434:79;;163489:10;;;;;;;;;-1:-1:-1;;;;;163489:10:0;-1:-1:-1;;;;;163489:22:0;;:24;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;163473:40;;;;:::i;:::-;;;163434:79;163624:7;;-1:-1:-1;;;;;163624:7:0;163616:30;;;;163615:85;;-1:-1:-1;163660:24:0;;-1:-1:-1;;;;;163660:24:0;163652:47;;163615:85;163611:172;;;163733:24;;;;;;;;;-1:-1:-1;;;;;163733:24:0;-1:-1:-1;;;;;163733:36:0;;: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;;;;;163939:21:0;;-1:-1:-1;163979:21:0;;163975:111;;164048:7;-1:-1:-1;;;;;164037:31:0;;: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;-1:-1:-1::0;;;;;184900:30:0::1;:18;184919:1;184900:21;;;;;;;;:::i;:::-;;::::0;;;::::1;::::0;;;::::1;::::0;-1:-1:-1;;;;;184900:21:0::1;:30:::0;184896:198:::1;;184983:1;184951:18;184970:1;184951:21;;;;;;;;:::i;:::-;;;;;;;;;:34;;;;;-1:-1:-1::0;;;;;184951:34:0::1;;;;;-1:-1:-1::0;;;;;184951:34:0::1;;;;;;185073:5;;184896:198;184876:3;;184825:280;;;;185117:6;:4;:6::i;:::-;185141:31;::::0;-1:-1:-1;;;;;1254:55:1;;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::-;-1:-1:-1;;;;;159967:27:0;;;;:64;;-1:-1:-1;159998:19:0;;-1:-1:-1;;;;;159998:19:0;:33;;159967:64;159963:122;;;160055:18;;;;;;;;;;;;;;159963:122;160131:5;:14;;-1:-1:-1;;;;;160131:14:0;;;;;;;;;;;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;;;;-1:-1:-1;;;;;160552:29:0;;;160516:66;160512:200;;;160624:15;;;;160599:10;:41;;-1:-1:-1;;;;;160599:41:0;;;;;;;;;;;160684:15;;;;160655:10;:45;;;;;;;;;;;160512:200;160796:15;;;;-1:-1:-1;;;;;160796:29:0;;;;;160795:66;;-1:-1:-1;160831:15:0;;;;-1:-1:-1;;;;;160831:29:0;;;160795:66;160791:217;;;160897:15;;;;160910:1;160878:35;;-1:-1:-1;;;;;160878:35:0;;;;;;;;;;;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;;;-1:-1:-1;;;;;22124:15:1;;;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;:::-;-1:-1:-1;;;;;177246:31:0;;177219:24;177246:31;;;:21;:31;;;;;;;177375:26;177268:8;177375:16;:26::i;:::-;-1:-1:-1;;;;;177465:31:0;;;;;;: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;-1:-1:-1;;;;;179029:39:0;;;;;;: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;-1:-1:-1;;;;;179582:27:0;;;;;;:17;:27;;;;;;;;179577:157;;-1:-1:-1;;;;;179626:27:0;;;;;;: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;;;-1:-1:-1;;;;;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;-1:-1:-1;;;;;139067:27:0;;;:69;;;;;:::i;:::-;139151:17;;139041:95;;-1:-1:-1;139151:21:0;139147:179;;139248:10;139237:30;;;;;;;;;;;;:::i;:::-;139229:85;;;;-1:-1:-1;;;139229:85:0;;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::-;-1:-1:-1;;;;;179894:22:0;;;179890:198;;179933:15;179951:16;179958:8;179951:6;:16::i;:::-;-1:-1:-1;;;;;179982:16:0;;;;;;: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;;;;-1:-1:-1;;;84517:81:0;;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;-1:-1:-1;;;;;80752:19:0;;;84609:60;;;;-1:-1:-1;;;84609:60:0;;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;-1:-1:-1;;;;;84724:11:0;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;;-1:-1:-1;;;87716:20:0;;;;;;;;:::i;14:154:1:-;-1:-1:-1;;;;;93:5:1;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;;-1:-1:-1;;;;;2500:62:1;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://b1d4074c9f3a0a0d84118d39446d8809008fea2a9d56a84706ea49f250cdaa16
Loading...
Loading
Loading...
Loading
Loading...
Loading
Net Worth in USD
$1,473.87
Net Worth in FRAX
1,789.695532
Token Allocations
FXS
99.37%
CRV
0.62%
CVX
0.01%
Multichain Portfolio | 35 Chains
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.