Source Code
| Transaction Hash |
|
Block
|
From
|
To
|
|||||
|---|---|---|---|---|---|---|---|---|---|
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Cross-Chain Transactions
Loading...
Loading
Contract Name:
VeFXSAggregator
Compiler Version
v0.8.26+commit.8a97fa7a
Contract Source Code (Solidity)
/**
*Submitted for verification at fraxscan.com on 2024-06-07
*/
// 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
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
struct LockedBalanceExtended {
uint256 id;
uint128 index;
int128 amount;
uint128 end;
}
/// @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 location The address where the lock is being held
/// @param estimatedCurrLockVeFXS Estimated veFXS of this lock based on amount, end, and when this struct was generated
struct LockedBalanceExtendedV2 {
uint256 id;
uint128 index;
int128 amount;
uint128 end;
address location;
uint256 estimatedCurrLockVeFXS;
}
/// @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 public totalSupplyStored;
/// @notice The block on Mainnet when the veFXS totalSupply was read
uint128 public blkWhenTotalSupplyRead;
/// @notice The timestamp on Mainnet when the veFXS totalSupply was read
uint128 public 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 _initBlkWhenTotalSupplyRead Initial/seed value of blkWhenTotalSupplyRead
* @param _initTsWhenTtlSupplyRead Initial/seed value of tsWhenTotalSupplyRead
*/
constructor(
address _owner,
address _bot,
uint256 _initTtlSupplyStored,
uint128 _initBlkWhenTotalSupplyRead,
uint128 _initTsWhenTtlSupplyRead
) OwnedV2(_owner) {
// Set bot address
botAddress = _bot;
// Set seed values
totalSupplyStored = _initTtlSupplyStored;
blkWhenTotalSupplyRead = _initBlkWhenTotalSupplyRead;
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 _blk Block when the totalSupply was read on Mainnet
/// @param _ts Timestamp when the totalSupply was read on Mainnet
function totalSupplyExtra() external view returns (uint256 _totalSupply, uint128 _blk, uint128 _ts) {
return (totalSupplyStored, blkWhenTotalSupplyRead, tsWhenTotalSupplyRead);
}
// ==============================================================================
// BOT FUNCTIONS
// ==============================================================================
/// @notice Set the most recent totalSupply from Mainnet veFXS
/// @param _totalSupply The last reported Mainnet veFXS totalSupply
/// @param _blk Block when the totalSupply was read on Mainnet
/// @param _ts Timestamp when the totalSupply was read on Mainnet
function updateInfo(uint256 _totalSupply, uint128 _blk, uint128 _ts) external onlyByOwnBot {
totalSupplyStored = _totalSupply;
blkWhenTotalSupplyRead = _blk;
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 blk Block when the totalSupply was read on Mainnet
/// @param ts Timestamp when the totalSupply was read on Mainnet
event InfoUpdated(uint256 totalSupply, uint128 blk, 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 FXS_CONVERSION_START_TIMESTAMP() 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 fpis() 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, uint256);
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 fpis;
uint256 public constant VOTE_END_POWER_BASIS_POINTS_UINT256 = 3330;
uint256 public constant MAX_BASIS_POINTS_UINT256 = 10_000;
/**
* @notice Contract constructor
* @param _FPISLocker Address of the FPISLocker contract
*/
constructor(address _FPISLocker) {
lFPIS = IFPISLocker(_FPISLocker);
fpis = IERC20Metadata(lFPIS.fpis());
}
/**
* @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)) * VOTE_END_POWER_BASIS_POINTS_UINT256) / MAX_BASIS_POINTS_UINT256;
}
// 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.VOTE_WEIGHT_MULTIPLIER_INT128()) /
lFPIS.MAXTIME_INT128() /
lFPIS.MAX_BASIS_POINTS_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])) * VOTE_END_POWER_BASIS_POINTS_UINT256) /
MAX_BASIS_POINTS_UINT256;
} 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)) * VOTE_END_POWER_BASIS_POINTS_UINT256) /
MAX_BASIS_POINTS_UINT256;
} 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/VeFXSAggregator.sol
// ====================================================================
// | ______ _______ |
// | / _____________ __ __ / ____(_____ ____ _____ ________ |
// | / /_ / ___/ __ `| |/_/ / /_ / / __ \/ __ `/ __ \/ ___/ _ \ |
// | / __/ / / / /_/ _> < / __/ / / / / / /_/ / / / / /__/ __/ |
// | /_/ /_/ \__,_/_/|_| /_/ /_/_/ /_/\__,_/_/ /_/\___/\___/ |
// | |
// ====================================================================
// ========================= VeFXSAggregator ==========================
// ====================================================================
// Looks at various sources of veFXS for a given address. Also gives totalSupply
// Includes:
// 1) L1veFXS: Lives on Fraxtal. Users can prove their Ethereum Mainnet vefxs.vy balance and end time so it is visible on Fraxtal
// 2) VestedFXS: Fraxtal-native veFXS. Basically the same as Mainnet vefxs.vy but lives on Fraxtal
// 3) FPISLocker: Locked FPIS on Fraxtal that eventually will be converted to FXS per https://snapshot.org/#/frax.eth/proposal/0x9ec68015d6f6fd185f600a255e494f4ff926bbdd9b268f4bd712983a6e68fb5a
// 4+) Future capability to add even more sources of veFXS
// Frax Finance: https://github.com/FraxFinance
// Primary Author(s)
// Travis Moore: https://github.com/FortisFortuna
// Reviewer(s) / Contributor(s)
// Jan Turk: https://github.com/ThunderDeliverer
// Dennis: https://github.com/denett
// 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 VeFXSAggregator is OwnedV2AutoMsgSender, ReentrancyGuard, IveFXSStructs {
using SafeERC20 for ERC20;
// ==============================================================================
// STATE VARIABLES
// ==============================================================================
// Instances
// -------------------------
/// @notice The Fraxtal veFXS contract
IVestedFXS public veFXS;
/// @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 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;
// Addresses
// -------------------------
/// @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;
// Misc
// -------------------------
/// @notice If the contract was initialized
bool wasInitialized;
/// @dev reserve extra storage for future upgrades
uint256[50] private __gap;
// ==============================================================================
// STRUCTS
// ==============================================================================
/// @notice A more detailed breakdown of the veFXS supply
/// @param vestedFXSTotal Fraxtal-native VestedFXS totalSupply
/// @param fpisLockerTotal FPISLocker's totalSupply
/// @param l1veFXSTotal Sum of L1veFXS as reported by the L1VeFXSTotalSupplyOracle
/// @param otherSourcesTotal Sum of the totalSupply's of other veFXS sources
/// @param grandTotal Grand totalSupply of all veFXS sources
struct DetailedTotalSupplyInfo {
uint256 vestedFXSTotal;
uint256 fpisLockerTotal;
uint256 l1veFXSTotal;
uint256 otherSourcesTotal;
uint256 grandTotal;
}
// ==============================================================================
// 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();
_;
}
// ==============================================================================
// CONSTRUCTOR
// ==============================================================================
constructor() {
// Set the contract as initialized
wasInitialized = true;
}
/**
* @notice Initialize contract
* @param _owner The owner of this contract
* @param _timelockAddress Address of the timelock
* @param _veAddresses The addresses: 0: veFXS, 1: veFXSUtils, 2: FPIS Locker, 3: FPISLockerUtils, 4: L1VeFXS, 5: L1VeFXSTotalSupplyOracle
*/
function initialize(address _owner, address _timelockAddress, address[6] memory _veAddresses) public {
// Safety checks - no validation on admin in case this is initialized without admin
if (wasInitialized) revert InitializeFailed();
// Set owner for OwnedV2
owner = _owner;
// Set misc addresses
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]);
}
}
// ==============================================================================
// VIEWS
// ==============================================================================
/// @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; i < addlVeContractsArr.length; ) {
address _veAddr = addlVeContractsArr[i];
if (_veAddr != address(0)) {
_currBal += IVestedFXS(_veAddr).balanceOf(_user);
}
unchecked {
++i;
}
}
}
/// @notice Detailed veFXS totalSupply from multiple different sources, such as the FPIS Locker, L1VeFXS, and Fraxtal veFXS. Non-checkpointed L1VeFXS is excluded
/// @return _supplyInfo Detailed breakdown of veFXS from different sources
function ttlCombinedVeFXSTotalSupplyDetailed() public view returns (DetailedTotalSupplyInfo memory _supplyInfo) {
// Look at the OG 3 sources first
// ===========================
// VestedFXS on Fraxtal
_supplyInfo.vestedFXSTotal = veFXS.totalSupply();
_supplyInfo.grandTotal = _supplyInfo.vestedFXSTotal;
// console2.log("{agg} veFXS.totalSupply(): %s", _supplyInfo.vestedFXSTotal);
// (Optional) FPIS Locker on Fraxtal
if (address(fpisLocker) != address(0)) {
_supplyInfo.fpisLockerTotal = fpisLocker.totalSupply();
_supplyInfo.grandTotal += _supplyInfo.fpisLockerTotal;
// console2.log("{agg} fpisLocker.totalSupply(): %s", _supplyInfo.fpisLockerTotal);
}
// (Optional) L1VeFXS: snapshot of Ethereum Mainnet veFXS. Lives on Fraxtal
if ((address(l1veFXS) != address(0)) && (address(l1VeFXSTotalSupplyOracle) != address(0))) {
_supplyInfo.l1veFXSTotal = l1VeFXSTotalSupplyOracle.totalSupply();
_supplyInfo.grandTotal += _supplyInfo.l1veFXSTotal;
// console2.log("{agg} l1VeFXSTotalSupplyOracle.totalSupply(): %s", _supplyInfo.l1veFXSTotal);
}
// (Optional) Look at any extra veFXS sources
for (uint256 i; i < addlVeContractsArr.length; ) {
address _veAddr = addlVeContractsArr[i];
if (_veAddr != address(0)) {
uint256 _thisSupply = IVestedFXS(_veAddr).totalSupply();
_supplyInfo.otherSourcesTotal += _thisSupply;
_supplyInfo.grandTotal += _thisSupply;
// console2.log("{agg} addlVeContractsArr[%s].totalSupply(): %s", i, _thisSupply);
}
unchecked {
++i;
}
}
}
/// @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
/// @dev Summarized version of ttlCombinedVeFXSTotalSupplyDetailed
function ttlCombinedVeFXSTotalSupply() public view returns (uint256 _totalSupply) {
DetailedTotalSupplyInfo memory _supplyInfo = ttlCombinedVeFXSTotalSupplyDetailed();
_totalSupply = _supplyInfo.grandTotal;
}
/// @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
/// @param _estimateCrudeVeFXS False to save gas. True to add the lock's estimated veFXS
/// @return _currActiveLocks Array of LockedBalanceExtendedV2 structs (all active locks)
function getAllCurrActiveLocks(
address _account,
bool _estimateCrudeVeFXS
) public view returns (LockedBalanceExtendedV2[] 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;
LockedBalanceExtendedV2[] memory _tmpActiveLocks = new LockedBalanceExtendedV2[](_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];
// (Optional) Estimate the lock's veFXS based on amount, end, and block.timestamp
uint256 _estimatedVeFXS;
if (_estimateCrudeVeFXS) {
_estimatedVeFXS = veFXSUtils.getCrudeExpectedVeFXSOneLock(
_vestedFXSLockInfo.amount,
_vestedFXSLockInfo.end - uint128(block.timestamp)
);
}
// Add to the temp array
_tmpActiveLocks[_activeLockIdx] = LockedBalanceExtendedV2({
id: _vestedFXSLockInfo.id,
index: _vestedFXSLockInfo.index,
amount: _vestedFXSLockInfo.amount,
end: _vestedFXSLockInfo.end,
location: address(veFXS),
estimatedCurrLockVeFXS: _estimatedVeFXS
});
// 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) {
// (Optional) Estimate the lock's veFXS based on amount, end, and block.timestamp
uint256 _estimatedVeFXS;
if (_estimateCrudeVeFXS) {
_estimatedVeFXS = lFpisUtils.getCrudeExpectedLFPISOneLock(
_fpisLockInfo.amount,
_fpisLockInfo.end - uint128(block.timestamp)
);
}
// Need to save as LockedBalanceExtendedV2
_tmpActiveLocks[_activeLockIdx] = LockedBalanceExtendedV2({
id: _fpisLockInfo.id,
index: _fpisLockInfo.index,
amount: _fpisLockInfo.amount,
end: _fpisLockInfo.end,
location: address(fpisLocker),
estimatedCurrLockVeFXS: _estimatedVeFXS
});
// 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 LockedBalanceExtendedV2 and push into _currCombinedLockBalExtds if it is active. There is only one lock too
if (_l1LockedBalance.end > block.timestamp) {
// (Optional) Estimate the lock's veFXS based on amount, end, and block.timestamp
uint256 _estimatedVeFXS;
if (_estimateCrudeVeFXS) {
_estimatedVeFXS = l1veFXS.balanceOf(_account);
}
// Add to the temp array
_tmpActiveLocks[_activeLockIdx] = LockedBalanceExtendedV2({
id: 0,
index: 0,
amount: int128(_l1LockedBalance.amount),
end: _l1LockedBalance.end,
location: address(l1veFXS),
estimatedCurrLockVeFXS: _estimatedVeFXS
});
// Increase the active lock index
++_activeLockIdx;
}
}
// (Optional) Look in the extra veFXS sources next. They should all be IVestedFXS ABI compliant
for (uint256 i; i < addlVeContractsArr.length; ) {
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 j; j < _addlVeFXSLockedBalExtds.length; ) {
// Save tmp variable to memory
IveFXSStructs.LockedBalanceExtended memory _addVeFXSLockInfo = _addlVeFXSLockedBalExtds[j];
// (Optional) Estimate the lock's veFXS based on amount, end, and block.timestamp
uint256 _estimatedVeFXS;
if (_estimateCrudeVeFXS) {
_estimatedVeFXS = IVestedFXSUtils(IVestedFXS(_veAddr).veFxsUtils())
.getCrudeExpectedVeFXSOneLock(
_addVeFXSLockInfo.amount,
_addVeFXSLockInfo.end - uint128(block.timestamp)
);
}
// Add to the temporary array
_tmpActiveLocks[_activeLockIdx] = LockedBalanceExtendedV2({
id: _addVeFXSLockInfo.id,
index: _addVeFXSLockInfo.index,
amount: _addVeFXSLockInfo.amount,
end: _addVeFXSLockInfo.end,
location: _veAddr,
estimatedCurrLockVeFXS: _estimatedVeFXS
});
// Increase the active lock index
++_activeLockIdx;
unchecked {
++j;
}
}
}
unchecked {
++i;
}
}
// Allocate the return array with only the number of active locks
_currActiveLocks = new LockedBalanceExtendedV2[](_activeLockIdx);
// Fill the return array
for (uint256 i; i < _currActiveLocks.length; ) {
_currActiveLocks[i] = _tmpActiveLocks[i];
unchecked {
++i;
}
}
}
/// @notice Get all the expired locks for a user
/// @param _account The account to get the locks for
/// @return _expiredLocks Array of LockedBalanceExtendedV2 structs (all expired locks)
/// @dev Technically could combine with getAllCurrActiveLocks to save gas, but getAllExpiredLocks is mainly intended for a UI
function getAllExpiredLocks(address _account) public view returns (LockedBalanceExtendedV2[] memory _expiredLocks) {
// Prepare to allocate the return array. Not all of the locks will be expired.
// 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 _expiredLockIdx = 0;
LockedBalanceExtendedV2[] memory _tmpExpiredLocks = new LockedBalanceExtendedV2[](_maxArrSize);
// Go through the OG 3 sources first
// Fraxtal veFXS
// -------------------------
{
// Get the LockedBalanceExtendeds
LockedBalanceExtended[] memory _fxtlVeFXSLockedBalExtds = (veFXSUtils.getDetailedUserLockInfo(_account))
.expiredLocks;
// 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];
// Add to the temp array
_tmpExpiredLocks[_expiredLockIdx] = LockedBalanceExtendedV2({
id: _vestedFXSLockInfo.id,
index: _vestedFXSLockInfo.index,
amount: _vestedFXSLockInfo.amount,
end: _vestedFXSLockInfo.end,
location: address(veFXS),
estimatedCurrLockVeFXS: 0
});
// Increase the expired lock index
++_expiredLockIdx;
unchecked {
++i;
}
}
}
// (Optional) FPIS Locker
// -------------------------
if (address(fpisLocker) != address(0)) {
// Get the LockedBalanceExtendeds
IlFPISStructs.LockedBalanceExtended[] memory _fpisLockerLockedBalExtds = (
lFpisUtils.getDetailedUserLockInfo(_account)
).expiredLocks;
// 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];
// Need to save as LockedBalanceExtendedV2
_tmpExpiredLocks[_expiredLockIdx] = LockedBalanceExtendedV2({
id: _fpisLockInfo.id,
index: _fpisLockInfo.index,
amount: _fpisLockInfo.amount,
end: _fpisLockInfo.end,
location: address(fpisLocker),
estimatedCurrLockVeFXS: 0
});
// Increase the expired lock index
++_expiredLockIdx;
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 LockedBalanceExtendedV2 and push into _currCombinedLockBalExtds if it is expired. There is only one lock too
if (_l1LockedBalance.end <= block.timestamp) {
// Add to the temp array
_tmpExpiredLocks[_expiredLockIdx] = LockedBalanceExtendedV2({
id: 0,
index: 0,
amount: int128(_l1LockedBalance.amount),
end: _l1LockedBalance.end,
location: address(l1veFXS),
estimatedCurrLockVeFXS: 0
});
// Increase the expired lock index
++_expiredLockIdx;
}
}
// (Optional) Look in the extra veFXS sources next. They should all be IVestedFXS ABI compliant
for (uint256 i; i < addlVeContractsArr.length; ) {
address _veAddr = addlVeContractsArr[i];
if (_veAddr != address(0)) {
// Get the expired locks
LockedBalanceExtended[] memory _addlVeFXSLockedBalExtds = (
IVestedFXSUtils(IVestedFXS(_veAddr).veFxsUtils()).getDetailedUserLockInfo(_account)
).expiredLocks;
// Loop though the expired locks and add them to the combined array
for (uint256 j; j < _addlVeFXSLockedBalExtds.length; ) {
// Save tmp variable to memory
IveFXSStructs.LockedBalanceExtended memory _addVeFXSLockInfo = _addlVeFXSLockedBalExtds[j];
// Add to the temporary array
_tmpExpiredLocks[_expiredLockIdx] = LockedBalanceExtendedV2({
id: _addVeFXSLockInfo.id,
index: _addVeFXSLockInfo.index,
amount: _addVeFXSLockInfo.amount,
end: _addVeFXSLockInfo.end,
location: _veAddr,
estimatedCurrLockVeFXS: 0
});
// Increase the expired lock index
++_expiredLockIdx;
unchecked {
++j;
}
}
}
unchecked {
++i;
}
}
// Allocate the return array with only the number of expired locks
_expiredLocks = new LockedBalanceExtendedV2[](_expiredLockIdx);
// Fill the return array
for (uint256 i; i < _expiredLocks.length; ) {
_expiredLocks[i] = _tmpExpiredLocks[i];
unchecked {
++i;
}
}
}
// ==============================================================================
// MUTATIVE FUNCTIONS
// ==============================================================================
// None...
// ==============================================================================
// RESTRICTED FUNCTIONS
// ==============================================================================
/// @notice Adds an additional veFXS-like contract
/// @param _addr The contract to added
function addAddlVeFXSContract(address _addr) public onlyByOwnGov {
require(_addr != address(0), "Zero address detected");
// Check the ABI here to make sure it is veFXS-like
// None of these should revert
IVestedFXS(_addr).totalSupply();
IVestedFXS(_addr).balanceOf(address(0));
IVestedFXS(_addr).numLocks(address(0));
IVestedFXSUtils(IVestedFXS(_addr).veFxsUtils()).getDetailedUserLockInfo(address(0));
IVestedFXSUtils(IVestedFXS(_addr).veFxsUtils()).getCrudeExpectedVeFXSOneLock(1e18, 604_800);
require(addlVeContracts[_addr] == false, "Address already exists");
addlVeContracts[_addr] = true;
addlVeContractsArr.push(_addr);
emit AddlVeFXSContractAdded(_addr);
}
/// @notice Removes a veFXS-like contract. Will need to mass checkpoint on the yield distributor or other sources to reflect new stored total veFXS
/// @param _addr The contract to remove
function removeAddlVeFXSContract(address _addr) public onlyByOwnGov {
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;
}
}
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 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 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 Cannot initialize twice
error InitializeFailed();
/// @notice If you are trying to call a function not as the owner or timelock
error NotOwnerOrTimelock();
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"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":"TransferHelperTransferFailed","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":"fpisLocker","outputs":[{"internalType":"contract IFPISLocker","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"},{"internalType":"bool","name":"_estimateCrudeVeFXS","type":"bool"}],"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":"address","name":"location","type":"address"},{"internalType":"uint256","name":"estimatedCurrLockVeFXS","type":"uint256"}],"internalType":"struct IveFXSStructs.LockedBalanceExtendedV2[]","name":"_currActiveLocks","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"}],"name":"getAllExpiredLocks","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":"address","name":"location","type":"address"},{"internalType":"uint256","name":"estimatedCurrLockVeFXS","type":"uint256"}],"internalType":"struct IveFXSStructs.LockedBalanceExtendedV2[]","name":"_expiredLocks","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_owner","type":"address"},{"internalType":"address","name":"_timelockAddress","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":[{"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":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"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[6]","name":"_veAddresses","type":"address[6]"}],"name":"setAddresses","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_newTimelock","type":"address"}],"name":"setTimelock","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"timelockAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"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":[],"name":"ttlCombinedVeFXSTotalSupplyDetailed","outputs":[{"components":[{"internalType":"uint256","name":"vestedFXSTotal","type":"uint256"},{"internalType":"uint256","name":"fpisLockerTotal","type":"uint256"},{"internalType":"uint256","name":"l1veFXSTotal","type":"uint256"},{"internalType":"uint256","name":"otherSourcesTotal","type":"uint256"},{"internalType":"uint256","name":"grandTotal","type":"uint256"}],"internalType":"struct VeFXSAggregator.DetailedTotalSupplyInfo","name":"_supplyInfo","type":"tuple"}],"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"}]Contract Creation Code
6080604052348015600e575f80fd5b505f80546001600160a01b0319163390811782556040805192835260208301919091527fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c910160405180910390a160016002819055600c805460ff191690911790556144548061007d5f395ff3fe608060405234801561000f575f80fd5b50600436106101a5575f3560e01c806379ba5097116100e8578063c0f456bd11610093578063f0657ab61161006e578063f0657ab614610429578063f21b723514610431578063f5d812cb14610444578063f868139b14610464575f80fd5b8063c0f456bd146103e4578063d96658d9146103f6578063ee73e04614610409575f80fd5b80638da5cb5b116100c35780638da5cb5b1461039f578063a6bffe7b146103be578063bdacb303146103d1575f80fd5b806379ba5097146103645780637eb1554e1461036c5780638980f11f1461038c575f80fd5b80634bc66f3211610153578063576221561161012e57806357622156146102d55780637351bf96146102e8578063744f008d146102fb5780637873fae614610344575f80fd5b80634bc66f3214610280578063525456d2146102a057806353a47bb7146102b5575f80fd5b80631627540c116101835780631627540c1461021b57806319ff52fd1461022e5780632f9b12f81461024e575f80fd5b806303d8477f146101a9578063054d2d1e146101be57806314b64f7c146101d1575b5f80fd5b6101bc6101b7366004613cbe565b610484565b005b6101bc6101cc366004613cfe565b610b34565b6008546101f19073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b6101bc610229366004613cfe565b611146565b6003546101f19073ffffffffffffffffffffffffffffffffffffffff1681565b61027061025c366004613cfe565b600b6020525f908152604090205460ff1681565b6040519015158152602001610212565b6009546101f19073ffffffffffffffffffffffffffffffffffffffff1681565b6102a8611209565b6040516102129190613d20565b6001546101f19073ffffffffffffffffffffffffffffffffffffffff1681565b6101f16102e3366004613d78565b611276565b6101bc6102f6366004613e34565b6112ab565b610303611491565b60405161021291905f60a082019050825182526020830151602083015260408301516040830152606083015160608301526080830151608083015292915050565b6004546101f19073ffffffffffffffffffffffffffffffffffffffff1681565b6101bc6117fe565b61037f61037a366004613ecf565b6118f1565b6040516102129190613f06565b6101bc61039a366004613fb4565b612829565b5f546101f19073ffffffffffffffffffffffffffffffffffffffff1681565b61037f6103cc366004613cfe565b612916565b6101bc6103df366004613cfe565b6134ac565b600a545b604051908152602001610212565b6103e8610404366004613cfe565b613569565b6005546101f19073ffffffffffffffffffffffffffffffffffffffff1681565b6103e8613892565b6101bc61043f366004613cfe565b6138a6565b6006546101f19073ffffffffffffffffffffffffffffffffffffffff1681565b6007546101f19073ffffffffffffffffffffffffffffffffffffffff1681565b5f5473ffffffffffffffffffffffffffffffffffffffff1633148015906104c3575060095473ffffffffffffffffffffffffffffffffffffffff163314155b156104fa576040517ffee4291a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f6105086020830183613cfe565b73ffffffffffffffffffffffffffffffffffffffff160361058a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f7665465853206d757374206e6f7420626520307830000000000000000000000060448201526064015b60405180910390fd5b5f61059b6040830160208401613cfe565b73ffffffffffffffffffffffffffffffffffffffff1603610618576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601a60248201527f76654658535574696c73206d757374206e6f74206265203078300000000000006044820152606401610581565b5f6106296060830160408401613cfe565b73ffffffffffffffffffffffffffffffffffffffff16036106a6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f43616e6e6f742061646420465049534c6f636b657220796574000000000000006044820152606401610581565b5f6106b76080830160608401613cfe565b73ffffffffffffffffffffffffffffffffffffffff1603610734576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f43616e6e6f742061646420465049534c6f636b65725574696c732079657400006044820152606401610581565b5f61074560a0830160808401613cfe565b73ffffffffffffffffffffffffffffffffffffffff16036107c2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f43616e6e6f7420616464204c31566546585320796574000000000000000000006044820152606401610581565b5f6107d360c0830160a08401613cfe565b73ffffffffffffffffffffffffffffffffffffffff1603610876576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f43616e6e6f7420616464204c315665465853546f74616c537570706c794f726160448201527f636c6520796574000000000000000000000000000000000000000000000000006064820152608401610581565b6108836020820182613cfe565b600380547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff929092169190911790556108d86040820160208301613cfe565b600680547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff929092169190911790555f61092e6060830160408401613cfe565b73ffffffffffffffffffffffffffffffffffffffff161415801561097757505f61095e6080830160608401613cfe565b73ffffffffffffffffffffffffffffffffffffffff1614155b15610a275761098c6060820160408301613cfe565b600480547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff929092169190911790556109e16080820160608301613cfe565b600780547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff929092169190911790555b5f610a3860a0830160808401613cfe565b73ffffffffffffffffffffffffffffffffffffffff1614158015610a8157505f610a6860c0830160a08401613cfe565b73ffffffffffffffffffffffffffffffffffffffff1614155b15610b3157610a9660a0820160808301613cfe565b600580547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055610aeb60c0820160a08301613cfe565b600880547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff929092169190911790555b50565b5f5473ffffffffffffffffffffffffffffffffffffffff163314801590610b73575060095473ffffffffffffffffffffffffffffffffffffffff163314155b15610baa576040517ffee4291a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116610c27576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f5a65726f206164647265737320646574656374656400000000000000000000006044820152606401610581565b8073ffffffffffffffffffffffffffffffffffffffff166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610c70573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610c94919061400b565b506040517f70a082310000000000000000000000000000000000000000000000000000000081525f600482015273ffffffffffffffffffffffffffffffffffffffff8216906370a0823190602401602060405180830381865afa158015610cfd573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610d21919061400b565b506040517fb9ef08300000000000000000000000000000000000000000000000000000000081525f600482015273ffffffffffffffffffffffffffffffffffffffff82169063b9ef083090602401602060405180830381865afa158015610d8a573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610dae9190614046565b508073ffffffffffffffffffffffffffffffffffffffff166366d6bff96040518163ffffffff1660e01b8152600401602060405180830381865afa158015610df8573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610e1c919061406a565b6040517f3c5933120000000000000000000000000000000000000000000000000000000081525f600482015273ffffffffffffffffffffffffffffffffffffffff9190911690633c593312906024015f60405180830381865afa158015610e85573d5f803e3d5ffd5b505050506040513d5f823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052610eca91908101906141d5565b508073ffffffffffffffffffffffffffffffffffffffff166366d6bff96040518163ffffffff1660e01b8152600401602060405180830381865afa158015610f14573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610f38919061406a565b6040517f0c8d01e6000000000000000000000000000000000000000000000000000000008152670de0b6b3a7640000600482015262093a80602482015273ffffffffffffffffffffffffffffffffffffffff9190911690630c8d01e690604401602060405180830381865afa158015610fb3573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610fd7919061400b565b5073ffffffffffffffffffffffffffffffffffffffff81165f908152600b602052604090205460ff1615611067576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4164647265737320616c726561647920657869737473000000000000000000006044820152606401610581565b73ffffffffffffffffffffffffffffffffffffffff81165f818152600b6020908152604080832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001908117909155600a805491820181559093527fc65a7bb8d6351c1cf70c95a316cc6a92839c986682d98bc35f958f4883f9d2a890920180547fffffffffffffffffffffffff0000000000000000000000000000000000000000168417905590519182527f75ccbc951feec3500ed75b1652ef72542006274e6f34d220bc70e3342fce797e91015b60405180910390a150565b5f5473ffffffffffffffffffffffffffffffffffffffff163314611196576040517f5fc483c500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040519081527f906a1c6bd7e3091ea86693dd029a831c19049ce77f1dce2ce0bab1cacbabce229060200161113b565b6060600a80548060200260200160405190810160405280929190818152602001828054801561126c57602002820191905f5260205f20905b815473ffffffffffffffffffffffffffffffffffffffff168152600190910190602001808311611241575b5050505050905090565b600a8181548110611285575f80fd5b5f9182526020909120015473ffffffffffffffffffffffffffffffffffffffff16905081565b600c5460ff16156112e8576040517fd08e7ac200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f805473ffffffffffffffffffffffffffffffffffffffff8581167fffffffffffffffffffffffff000000000000000000000000000000000000000092831617909255600980548584169083161790558251600380548316918416919091179055602083015160068054909216908316179055604082015116158015906113885750606081015173ffffffffffffffffffffffffffffffffffffffff1615155b156113e95760408101516004805473ffffffffffffffffffffffffffffffffffffffff9283167fffffffffffffffffffffffff0000000000000000000000000000000000000000918216179091556060830151600780549190931691161790555b608081015173ffffffffffffffffffffffffffffffffffffffff161580159061142b575060a081015173ffffffffffffffffffffffffffffffffffffffff1615155b1561148c5760808101516005805473ffffffffffffffffffffffffffffffffffffffff9283167fffffffffffffffffffffffff00000000000000000000000000000000000000009182161790915560a0830151600880549190931691161790555b505050565b6114be6040518060a001604052805f81526020015f81526020015f81526020015f81526020015f81525090565b60035f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611528573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061154c919061400b565b808252608082015260045473ffffffffffffffffffffffffffffffffffffffff161561161d5760048054604080517f18160ddd000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff909216926318160ddd9282820192602092908290030181865afa1580156115dd573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611601919061400b565b602082018190526080820180516116199083906142f2565b9052505b60055473ffffffffffffffffffffffffffffffffffffffff161580159061165b575060085473ffffffffffffffffffffffffffffffffffffffff1615155b1561170a5760085f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156116ca573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906116ee919061400b565b604082018190526080820180516117069083906142f2565b9052505b5f5b600a548110156117fa575f600a828154811061172a5761172a613fde565b5f9182526020909120015473ffffffffffffffffffffffffffffffffffffffff16905080156117f1575f8173ffffffffffffffffffffffffffffffffffffffff166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561179d573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906117c1919061400b565b905080846060018181516117d591906142f2565b9052506080840180518291906117ec9083906142f2565b905250505b5060010161170c565b5090565b60015473ffffffffffffffffffffffffffffffffffffffff16331461184f576040517fd74b334e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f546001546040805173ffffffffffffffffffffffffffffffffffffffff93841681529290911660208301527fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c910160405180910390a1600180545f80547fffffffffffffffffffffffff000000000000000000000000000000000000000090811673ffffffffffffffffffffffffffffffffffffffff841617909155169055565b6003546040517fb9ef083000000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff84811660048301526060925f9291169063b9ef083090602401602060405180830381865afa158015611963573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906119879190614046565b6004546fffffffffffffffffffffffffffffffff91909116915073ffffffffffffffffffffffffffffffffffffffff1615611a6f57600480546040517fb9ef083000000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8781169382019390935291169063b9ef083090602401602060405180830381865afa158015611a2c573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611a509190614046565b611a6c906fffffffffffffffffffffffffffffffff16826142f2565b90505b60055473ffffffffffffffffffffffffffffffffffffffff1615801590611aad575060085473ffffffffffffffffffffffffffffffffffffffff1615155b15611ac057611abd6001826142f2565b90505b5f5b600a54811015611bbf575f600a8281548110611ae057611ae0613fde565b5f9182526020909120015473ffffffffffffffffffffffffffffffffffffffff1690508015611bb6576040517fb9ef083000000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff878116600483015282169063b9ef083090602401602060405180830381865afa158015611b73573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611b979190614046565b611bb3906fffffffffffffffffffffffffffffffff16846142f2565b92505b50600101611ac2565b505f808267ffffffffffffffff811115611bdb57611bdb613d8f565b604051908082528060200260200182016040528015611c5857816020015b6040805160c0810182525f8082526020808301829052928201819052606082018190526080820181905260a082015282527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff909201910181611bf95790505b506006546040517f3c59331200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff89811660048301529293505f9290911690633c593312906024015f60405180830381865afa158015611ccb573d5f803e3d5ffd5b505050506040513d5f823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052611d1091908101906141d5565b6060015190505f5b8151811015611ee0575f828281518110611d3457611d34613fde565b602002602001015190505f8815611e10576006546040830151606084015173ffffffffffffffffffffffffffffffffffffffff90921691630c8d01e69190611d7d90429061430b565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b168152600f9290920b60048301526fffffffffffffffffffffffffffffffff166024820152604401602060405180830381865afa158015611de9573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611e0d919061400b565b90505b6040518060c00160405280835f0151815260200183602001516fffffffffffffffffffffffffffffffff1681526020018360400151600f0b815260200183606001516fffffffffffffffffffffffffffffffff16815260200160035f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200182815250858781518110611ebc57611ebc613fde565b602002602001018190525085611ed190614333565b95508260010192505050611d18565b505060045473ffffffffffffffffffffffffffffffffffffffff16156121a1576007546040517f3c59331200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff88811660048301525f921690633c593312906024015f60405180830381865afa158015611f6d573d5f803e3d5ffd5b505050506040513d5f823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052611fb291908101906141d5565b6060015190505f5b815181101561219e575f828281518110611fd657611fd6613fde565b602002602001015190504281606001516fffffffffffffffffffffffffffffffff161115612195575f88156120d0576007546040830151606084015173ffffffffffffffffffffffffffffffffffffffff90921691630e5f6d5d919061203d90429061430b565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b168152600f9290920b60048301526fffffffffffffffffffffffffffffffff166024820152604401602060405180830381865afa1580156120a9573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906120cd919061400b565b90505b6040518060c00160405280835f0151815260200183602001516fffffffffffffffffffffffffffffffff1681526020018360400151600f0b815260200183606001516fffffffffffffffffffffffffffffffff16815260200160045f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281525085878151811061217c5761217c613fde565b60200260200101819052508561219190614333565b9550505b50600101611fba565b50505b60055473ffffffffffffffffffffffffffffffffffffffff16158015906121df575060085473ffffffffffffffffffffffffffffffffffffffff1615155b156123b4576005546040517fcbf9fe5f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff88811660048301525f92169063cbf9fe5f90602401606060405180830381865afa158015612252573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906122769190614381565b905042816020015167ffffffffffffffff1611156123b2575f861561232a576005546040517f70a0823100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8a81166004830152909116906370a0823190602401602060405180830381865afa158015612303573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612327919061400b565b90505b6040805160c0810182525f8082526020808301919091528451600f0b928201929092529083015167ffffffffffffffff16606082015260055473ffffffffffffffffffffffffffffffffffffffff16608082015260a08101829052835184908690811061239957612399613fde565b6020026020010181905250836123ae90614333565b9350505b505b5f5b600a5481101561273b575f600a82815481106123d4576123d4613fde565b5f9182526020909120015473ffffffffffffffffffffffffffffffffffffffff1690508015612732575f8173ffffffffffffffffffffffffffffffffffffffff166366d6bff96040518163ffffffff1660e01b8152600401602060405180830381865afa158015612447573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061246b919061406a565b6040517f3c59331200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8b811660048301529190911690633c593312906024015f60405180830381865afa1580156124d6573d5f803e3d5ffd5b505050506040513d5f823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016820160405261251b91908101906141d5565b6060015190505f5b815181101561272f575f82828151811061253f5761253f613fde565b602002602001015190505f8a15612680578473ffffffffffffffffffffffffffffffffffffffff166366d6bff96040518163ffffffff1660e01b8152600401602060405180830381865afa158015612599573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906125bd919061406a565b73ffffffffffffffffffffffffffffffffffffffff16630c8d01e683604001514285606001516125ed919061430b565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b168152600f9290920b60048301526fffffffffffffffffffffffffffffffff166024820152604401602060405180830381865afa158015612659573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061267d919061400b565b90505b6040518060c00160405280835f0151815260200183602001516fffffffffffffffffffffffffffffffff1681526020018360400151600f0b815260200183606001516fffffffffffffffffffffffffffffffff1681526020018673ffffffffffffffffffffffffffffffffffffffff1681526020018281525087898151811061270b5761270b613fde565b60200260200101819052508761272090614333565b97508260010192505050612523565b50505b506001016123b6565b508167ffffffffffffffff81111561275557612755613d8f565b6040519080825280602002602001820160405280156127d257816020015b6040805160c0810182525f8082526020808301829052928201819052606082018190526080820181905260a082015282527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9092019101816127735790505b5093505f5b845181101561281f578181815181106127f2576127f2613fde565b602002602001015185828151811061280c5761280c613fde565b60209081029190910101526001016127d7565b5050505092915050565b5f5473ffffffffffffffffffffffffffffffffffffffff163314801590612868575060095473ffffffffffffffffffffffffffffffffffffffff163314155b1561289f576040517ffee4291a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f546128c390839073ffffffffffffffffffffffffffffffffffffffff1683613b7e565b6040805173ffffffffffffffffffffffffffffffffffffffff84168152602081018390527f55350610fe57096d8c0ffa30beede987326bccfcb0b4415804164d0dd50ce8b1910160405180910390a15050565b6003546040517fb9ef083000000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff83811660048301526060925f9291169063b9ef083090602401602060405180830381865afa158015612988573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906129ac9190614046565b6004546fffffffffffffffffffffffffffffffff91909116915073ffffffffffffffffffffffffffffffffffffffff1615612a9457600480546040517fb9ef083000000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8681169382019390935291169063b9ef083090602401602060405180830381865afa158015612a51573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612a759190614046565b612a91906fffffffffffffffffffffffffffffffff16826142f2565b90505b60055473ffffffffffffffffffffffffffffffffffffffff1615801590612ad2575060085473ffffffffffffffffffffffffffffffffffffffff1615155b15612ae557612ae26001826142f2565b90505b5f5b600a54811015612be4575f600a8281548110612b0557612b05613fde565b5f9182526020909120015473ffffffffffffffffffffffffffffffffffffffff1690508015612bdb576040517fb9ef083000000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff868116600483015282169063b9ef083090602401602060405180830381865afa158015612b98573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612bbc9190614046565b612bd8906fffffffffffffffffffffffffffffffff16846142f2565b92505b50600101612ae7565b505f808267ffffffffffffffff811115612c0057612c00613d8f565b604051908082528060200260200182016040528015612c7d57816020015b6040805160c0810182525f8082526020808301829052928201819052606082018190526080820181905260a082015282527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff909201910181612c1e5790505b506006546040517f3c59331200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff88811660048301529293505f9290911690633c593312906024015f60405180830381865afa158015612cf0573d5f803e3d5ffd5b505050506040513d5f823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052612d3591908101906141d5565b6080015190505f5b8151811015612e2f575f828281518110612d5957612d59613fde565b602002602001015190506040518060c00160405280825f0151815260200182602001516fffffffffffffffffffffffffffffffff1681526020018260400151600f0b815260200182606001516fffffffffffffffffffffffffffffffff16815260200160035f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020015f815250848681518110612e0f57612e0f613fde565b602002602001018190525084612e2490614333565b945050600101612d3d565b505060045473ffffffffffffffffffffffffffffffffffffffff1615612ffe576007546040517f3c59331200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff87811660048301525f921690633c593312906024015f60405180830381865afa158015612ebc573d5f803e3d5ffd5b505050506040513d5f823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052612f0191908101906141d5565b6080015190505f5b8151811015612ffb575f828281518110612f2557612f25613fde565b602002602001015190506040518060c00160405280825f0151815260200182602001516fffffffffffffffffffffffffffffffff1681526020018260400151600f0b815260200182606001516fffffffffffffffffffffffffffffffff16815260200160045f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020015f815250848681518110612fdb57612fdb613fde565b602002602001018190525084612ff090614333565b945050600101612f09565b50505b60055473ffffffffffffffffffffffffffffffffffffffff161580159061303c575060085473ffffffffffffffffffffffffffffffffffffffff1615155b15613173576005546040517fcbf9fe5f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff87811660048301525f92169063cbf9fe5f90602401606060405180830381865afa1580156130af573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906130d39190614381565b905042816020015167ffffffffffffffff1611613171576040805160c0810182525f80825260208083018290528451600f0b938301939093529183015167ffffffffffffffff16606082015260055473ffffffffffffffffffffffffffffffffffffffff16608082015260a0810191909152825183908590811061315957613159613fde565b60200260200101819052508261316e90614333565b92505b505b5f5b600a548110156133bf575f600a828154811061319357613193613fde565b5f9182526020909120015473ffffffffffffffffffffffffffffffffffffffff16905080156133b6575f8173ffffffffffffffffffffffffffffffffffffffff166366d6bff96040518163ffffffff1660e01b8152600401602060405180830381865afa158015613206573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061322a919061406a565b6040517f3c59331200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8a811660048301529190911690633c593312906024015f60405180830381865afa158015613295573d5f803e3d5ffd5b505050506040513d5f823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526132da91908101906141d5565b6080015190505f5b81518110156133b3575f8282815181106132fe576132fe613fde565b602002602001015190506040518060c00160405280825f0151815260200182602001516fffffffffffffffffffffffffffffffff1681526020018260400151600f0b815260200182606001516fffffffffffffffffffffffffffffffff1681526020018573ffffffffffffffffffffffffffffffffffffffff1681526020015f81525086888151811061339357613393613fde565b6020026020010181905250866133a890614333565b9650506001016132e2565b50505b50600101613175565b508167ffffffffffffffff8111156133d9576133d9613d8f565b60405190808252806020026020018201604052801561345657816020015b6040805160c0810182525f8082526020808301829052928201819052606082018190526080820181905260a082015282527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9092019101816133f75790505b5093505f5b84518110156134a35781818151811061347657613476613fde565b602002602001015185828151811061349057613490613fde565b602090810291909101015260010161345b565b50505050919050565b5f5473ffffffffffffffffffffffffffffffffffffffff1633148015906134eb575060095473ffffffffffffffffffffffffffffffffffffffff163314155b15613522576040517ffee4291a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600980547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b6003546040517f70a0823100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff83811660048301525f9216906370a0823190602401602060405180830381865afa1580156135d7573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906135fb919061400b565b60045490915073ffffffffffffffffffffffffffffffffffffffff16156136bd57600480546040517f70a0823100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff858116938201939093529116906370a0823190602401602060405180830381865afa15801561368c573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906136b0919061400b565b6136ba90826142f2565b90505b60055473ffffffffffffffffffffffffffffffffffffffff16158015906136fb575060085473ffffffffffffffffffffffffffffffffffffffff1615155b1561379f576005546040517f70a0823100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8481166004830152909116906370a0823190602401602060405180830381865afa15801561376e573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190613792919061400b565b61379c90826142f2565b90505b5f5b600a5481101561388c575f600a82815481106137bf576137bf613fde565b5f9182526020909120015473ffffffffffffffffffffffffffffffffffffffff1690508015613883576040517f70a0823100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff85811660048301528216906370a0823190602401602060405180830381865afa158015613852573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190613876919061400b565b61388090846142f2565b92505b506001016137a1565b50919050565b5f8061389c611491565b6080015192915050565b5f5473ffffffffffffffffffffffffffffffffffffffff1633148015906138e5575060095473ffffffffffffffffffffffffffffffffffffffff163314155b1561391c576040517ffee4291a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116613999576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f5a65726f206164647265737320646574656374656400000000000000000000006044820152606401610581565b73ffffffffffffffffffffffffffffffffffffffff81165f908152600b602052604090205460ff161515600114613a2c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f41646472657373206e6f6e6578697374656e74000000000000000000000000006044820152606401610581565b73ffffffffffffffffffffffffffffffffffffffff81165f908152600b6020526040812080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001690555b600a54811015613b37578173ffffffffffffffffffffffffffffffffffffffff16600a8281548110613aab57613aab613fde565b5f9182526020909120015473ffffffffffffffffffffffffffffffffffffffff1603613b2f575f600a8281548110613ae557613ae5613fde565b905f5260205f20015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550613b37565b600101613a77565b5060405173ffffffffffffffffffffffffffffffffffffffff821681527ff3517f912cde760e82811897047177df419c7aa16326d5710e6b425a8a7d10359060200161113b565b6040805173ffffffffffffffffffffffffffffffffffffffff8481166024830152604480830185905283518084039091018152606490920183526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb0000000000000000000000000000000000000000000000000000000017905291515f92839290871691613c1491906143ed565b5f604051808303815f865af19150503d805f8114613c4d576040519150601f19603f3d011682016040523d82523d5f602084013e613c52565b606091505b5091509150811580613c805750805115801590613c80575080806020019051810190613c7e9190614403565b155b15613cb7576040517f19a9708500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050505050565b5f60c08284031215613cce575f80fd5b8260c08301111561388c575f80fd5b73ffffffffffffffffffffffffffffffffffffffff81168114610b31575f80fd5b5f60208284031215613d0e575f80fd5b8135613d1981613cdd565b9392505050565b602080825282518282018190525f918401906040840190835b81811015613d6d57835173ffffffffffffffffffffffffffffffffffffffff16835260209384019390920191600101613d39565b509095945050505050565b5f60208284031215613d88575f80fd5b5035919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b60405160c0810167ffffffffffffffff81118282101715613ddf57613ddf613d8f565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715613e2c57613e2c613d8f565b604052919050565b5f805f6101008486031215613e47575f80fd5b8335613e5281613cdd565b92506020840135613e6281613cdd565b9150605f84018513613e72575f80fd5b613e7c60c0613de5565b80610100860187811115613e8e575f80fd5b604087015b81811015613eb4578035613ea681613cdd565b845260209384019301613e93565b505080925050509250925092565b8015158114610b31575f80fd5b5f8060408385031215613ee0575f80fd5b8235613eeb81613cdd565b91506020830135613efb81613ec2565b809150509250929050565b602080825282518282018190525f918401906040840190835b81811015613d6d578351805184526fffffffffffffffffffffffffffffffff60208201511660208501526040810151600f0b60408501526fffffffffffffffffffffffffffffffff606082015116606085015273ffffffffffffffffffffffffffffffffffffffff608082015116608085015260a081015160a08501525060c083019250602084019350600181019050613f1f565b5f8060408385031215613fc5575f80fd5b8235613fd081613cdd565b946020939093013593505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b5f6020828403121561401b575f80fd5b5051919050565b80516fffffffffffffffffffffffffffffffff81168114614041575f80fd5b919050565b5f60208284031215614056575f80fd5b613d1982614022565b805161404181613cdd565b5f6020828403121561407a575f80fd5b8151613d1981613cdd565b8051600f81900b8114614041575f80fd5b5f82601f8301126140a5575f80fd5b8151602083015f8067ffffffffffffffff8411156140c5576140c5613d8f565b60208460051b0190506140d781613de5565b84815260079490941b83019391505060208101868411156140f6575f80fd5b83831015614180575f6080848903121561410e575f80fd5b6040516080810167ffffffffffffffff8111828210171561413157614131613d8f565b6040528451808252915061414760208601614022565b602082015261415860408601614085565b604082015261416960608601614022565b6060820152825250608092909201916020016140f6565b5095945050505050565b5f82601f830112614199575f80fd5b6141a36060613de5565b8060608401858111156141b4575f80fd5b845b81811015613d6d576141c781614085565b8452602093840193016141b6565b5f602082840312156141e5575f80fd5b815167ffffffffffffffff8111156141fb575f80fd5b8201610100818503121561420d575f80fd5b614215613dbc565b61421e8261405f565b815260208281015190820152604082015167ffffffffffffffff811115614243575f80fd5b61424f86828501614096565b604083015250606082015167ffffffffffffffff81111561426e575f80fd5b61427a86828501614096565b606083015250608082015167ffffffffffffffff811115614299575f80fd5b6142a586828501614096565b6080830152506142b88560a0840161418a565b60a0820152949350505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b80820180821115614305576143056142c5565b92915050565b6fffffffffffffffffffffffffffffffff8281168282160390811115614305576143056142c5565b5f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203614363576143636142c5565b5060010190565b805167ffffffffffffffff81168114614041575f80fd5b5f6060828403128015614392575f80fd5b506040516060810167ffffffffffffffff811182821017156143b6576143b6613d8f565b6040526143c283614022565b81526143d06020840161436a565b60208201526143e16040840161436a565b60408201529392505050565b5f82518060208501845e5f920191825250919050565b5f60208284031215614413575f80fd5b8151613d1981613ec256fea2646970667358221220906e77c6f61b3057feae5009f729232e2975ab0fb6ae39d9a4d084df7d210dc164736f6c634300081a0033
Deployed Bytecode
0x608060405234801561000f575f80fd5b50600436106101a5575f3560e01c806379ba5097116100e8578063c0f456bd11610093578063f0657ab61161006e578063f0657ab614610429578063f21b723514610431578063f5d812cb14610444578063f868139b14610464575f80fd5b8063c0f456bd146103e4578063d96658d9146103f6578063ee73e04614610409575f80fd5b80638da5cb5b116100c35780638da5cb5b1461039f578063a6bffe7b146103be578063bdacb303146103d1575f80fd5b806379ba5097146103645780637eb1554e1461036c5780638980f11f1461038c575f80fd5b80634bc66f3211610153578063576221561161012e57806357622156146102d55780637351bf96146102e8578063744f008d146102fb5780637873fae614610344575f80fd5b80634bc66f3214610280578063525456d2146102a057806353a47bb7146102b5575f80fd5b80631627540c116101835780631627540c1461021b57806319ff52fd1461022e5780632f9b12f81461024e575f80fd5b806303d8477f146101a9578063054d2d1e146101be57806314b64f7c146101d1575b5f80fd5b6101bc6101b7366004613cbe565b610484565b005b6101bc6101cc366004613cfe565b610b34565b6008546101f19073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b6101bc610229366004613cfe565b611146565b6003546101f19073ffffffffffffffffffffffffffffffffffffffff1681565b61027061025c366004613cfe565b600b6020525f908152604090205460ff1681565b6040519015158152602001610212565b6009546101f19073ffffffffffffffffffffffffffffffffffffffff1681565b6102a8611209565b6040516102129190613d20565b6001546101f19073ffffffffffffffffffffffffffffffffffffffff1681565b6101f16102e3366004613d78565b611276565b6101bc6102f6366004613e34565b6112ab565b610303611491565b60405161021291905f60a082019050825182526020830151602083015260408301516040830152606083015160608301526080830151608083015292915050565b6004546101f19073ffffffffffffffffffffffffffffffffffffffff1681565b6101bc6117fe565b61037f61037a366004613ecf565b6118f1565b6040516102129190613f06565b6101bc61039a366004613fb4565b612829565b5f546101f19073ffffffffffffffffffffffffffffffffffffffff1681565b61037f6103cc366004613cfe565b612916565b6101bc6103df366004613cfe565b6134ac565b600a545b604051908152602001610212565b6103e8610404366004613cfe565b613569565b6005546101f19073ffffffffffffffffffffffffffffffffffffffff1681565b6103e8613892565b6101bc61043f366004613cfe565b6138a6565b6006546101f19073ffffffffffffffffffffffffffffffffffffffff1681565b6007546101f19073ffffffffffffffffffffffffffffffffffffffff1681565b5f5473ffffffffffffffffffffffffffffffffffffffff1633148015906104c3575060095473ffffffffffffffffffffffffffffffffffffffff163314155b156104fa576040517ffee4291a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f6105086020830183613cfe565b73ffffffffffffffffffffffffffffffffffffffff160361058a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f7665465853206d757374206e6f7420626520307830000000000000000000000060448201526064015b60405180910390fd5b5f61059b6040830160208401613cfe565b73ffffffffffffffffffffffffffffffffffffffff1603610618576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601a60248201527f76654658535574696c73206d757374206e6f74206265203078300000000000006044820152606401610581565b5f6106296060830160408401613cfe565b73ffffffffffffffffffffffffffffffffffffffff16036106a6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f43616e6e6f742061646420465049534c6f636b657220796574000000000000006044820152606401610581565b5f6106b76080830160608401613cfe565b73ffffffffffffffffffffffffffffffffffffffff1603610734576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f43616e6e6f742061646420465049534c6f636b65725574696c732079657400006044820152606401610581565b5f61074560a0830160808401613cfe565b73ffffffffffffffffffffffffffffffffffffffff16036107c2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f43616e6e6f7420616464204c31566546585320796574000000000000000000006044820152606401610581565b5f6107d360c0830160a08401613cfe565b73ffffffffffffffffffffffffffffffffffffffff1603610876576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f43616e6e6f7420616464204c315665465853546f74616c537570706c794f726160448201527f636c6520796574000000000000000000000000000000000000000000000000006064820152608401610581565b6108836020820182613cfe565b600380547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff929092169190911790556108d86040820160208301613cfe565b600680547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff929092169190911790555f61092e6060830160408401613cfe565b73ffffffffffffffffffffffffffffffffffffffff161415801561097757505f61095e6080830160608401613cfe565b73ffffffffffffffffffffffffffffffffffffffff1614155b15610a275761098c6060820160408301613cfe565b600480547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff929092169190911790556109e16080820160608301613cfe565b600780547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff929092169190911790555b5f610a3860a0830160808401613cfe565b73ffffffffffffffffffffffffffffffffffffffff1614158015610a8157505f610a6860c0830160a08401613cfe565b73ffffffffffffffffffffffffffffffffffffffff1614155b15610b3157610a9660a0820160808301613cfe565b600580547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055610aeb60c0820160a08301613cfe565b600880547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff929092169190911790555b50565b5f5473ffffffffffffffffffffffffffffffffffffffff163314801590610b73575060095473ffffffffffffffffffffffffffffffffffffffff163314155b15610baa576040517ffee4291a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116610c27576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f5a65726f206164647265737320646574656374656400000000000000000000006044820152606401610581565b8073ffffffffffffffffffffffffffffffffffffffff166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610c70573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610c94919061400b565b506040517f70a082310000000000000000000000000000000000000000000000000000000081525f600482015273ffffffffffffffffffffffffffffffffffffffff8216906370a0823190602401602060405180830381865afa158015610cfd573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610d21919061400b565b506040517fb9ef08300000000000000000000000000000000000000000000000000000000081525f600482015273ffffffffffffffffffffffffffffffffffffffff82169063b9ef083090602401602060405180830381865afa158015610d8a573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610dae9190614046565b508073ffffffffffffffffffffffffffffffffffffffff166366d6bff96040518163ffffffff1660e01b8152600401602060405180830381865afa158015610df8573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610e1c919061406a565b6040517f3c5933120000000000000000000000000000000000000000000000000000000081525f600482015273ffffffffffffffffffffffffffffffffffffffff9190911690633c593312906024015f60405180830381865afa158015610e85573d5f803e3d5ffd5b505050506040513d5f823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052610eca91908101906141d5565b508073ffffffffffffffffffffffffffffffffffffffff166366d6bff96040518163ffffffff1660e01b8152600401602060405180830381865afa158015610f14573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610f38919061406a565b6040517f0c8d01e6000000000000000000000000000000000000000000000000000000008152670de0b6b3a7640000600482015262093a80602482015273ffffffffffffffffffffffffffffffffffffffff9190911690630c8d01e690604401602060405180830381865afa158015610fb3573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610fd7919061400b565b5073ffffffffffffffffffffffffffffffffffffffff81165f908152600b602052604090205460ff1615611067576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4164647265737320616c726561647920657869737473000000000000000000006044820152606401610581565b73ffffffffffffffffffffffffffffffffffffffff81165f818152600b6020908152604080832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001908117909155600a805491820181559093527fc65a7bb8d6351c1cf70c95a316cc6a92839c986682d98bc35f958f4883f9d2a890920180547fffffffffffffffffffffffff0000000000000000000000000000000000000000168417905590519182527f75ccbc951feec3500ed75b1652ef72542006274e6f34d220bc70e3342fce797e91015b60405180910390a150565b5f5473ffffffffffffffffffffffffffffffffffffffff163314611196576040517f5fc483c500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040519081527f906a1c6bd7e3091ea86693dd029a831c19049ce77f1dce2ce0bab1cacbabce229060200161113b565b6060600a80548060200260200160405190810160405280929190818152602001828054801561126c57602002820191905f5260205f20905b815473ffffffffffffffffffffffffffffffffffffffff168152600190910190602001808311611241575b5050505050905090565b600a8181548110611285575f80fd5b5f9182526020909120015473ffffffffffffffffffffffffffffffffffffffff16905081565b600c5460ff16156112e8576040517fd08e7ac200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f805473ffffffffffffffffffffffffffffffffffffffff8581167fffffffffffffffffffffffff000000000000000000000000000000000000000092831617909255600980548584169083161790558251600380548316918416919091179055602083015160068054909216908316179055604082015116158015906113885750606081015173ffffffffffffffffffffffffffffffffffffffff1615155b156113e95760408101516004805473ffffffffffffffffffffffffffffffffffffffff9283167fffffffffffffffffffffffff0000000000000000000000000000000000000000918216179091556060830151600780549190931691161790555b608081015173ffffffffffffffffffffffffffffffffffffffff161580159061142b575060a081015173ffffffffffffffffffffffffffffffffffffffff1615155b1561148c5760808101516005805473ffffffffffffffffffffffffffffffffffffffff9283167fffffffffffffffffffffffff00000000000000000000000000000000000000009182161790915560a0830151600880549190931691161790555b505050565b6114be6040518060a001604052805f81526020015f81526020015f81526020015f81526020015f81525090565b60035f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611528573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061154c919061400b565b808252608082015260045473ffffffffffffffffffffffffffffffffffffffff161561161d5760048054604080517f18160ddd000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff909216926318160ddd9282820192602092908290030181865afa1580156115dd573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611601919061400b565b602082018190526080820180516116199083906142f2565b9052505b60055473ffffffffffffffffffffffffffffffffffffffff161580159061165b575060085473ffffffffffffffffffffffffffffffffffffffff1615155b1561170a5760085f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156116ca573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906116ee919061400b565b604082018190526080820180516117069083906142f2565b9052505b5f5b600a548110156117fa575f600a828154811061172a5761172a613fde565b5f9182526020909120015473ffffffffffffffffffffffffffffffffffffffff16905080156117f1575f8173ffffffffffffffffffffffffffffffffffffffff166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561179d573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906117c1919061400b565b905080846060018181516117d591906142f2565b9052506080840180518291906117ec9083906142f2565b905250505b5060010161170c565b5090565b60015473ffffffffffffffffffffffffffffffffffffffff16331461184f576040517fd74b334e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f546001546040805173ffffffffffffffffffffffffffffffffffffffff93841681529290911660208301527fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c910160405180910390a1600180545f80547fffffffffffffffffffffffff000000000000000000000000000000000000000090811673ffffffffffffffffffffffffffffffffffffffff841617909155169055565b6003546040517fb9ef083000000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff84811660048301526060925f9291169063b9ef083090602401602060405180830381865afa158015611963573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906119879190614046565b6004546fffffffffffffffffffffffffffffffff91909116915073ffffffffffffffffffffffffffffffffffffffff1615611a6f57600480546040517fb9ef083000000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8781169382019390935291169063b9ef083090602401602060405180830381865afa158015611a2c573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611a509190614046565b611a6c906fffffffffffffffffffffffffffffffff16826142f2565b90505b60055473ffffffffffffffffffffffffffffffffffffffff1615801590611aad575060085473ffffffffffffffffffffffffffffffffffffffff1615155b15611ac057611abd6001826142f2565b90505b5f5b600a54811015611bbf575f600a8281548110611ae057611ae0613fde565b5f9182526020909120015473ffffffffffffffffffffffffffffffffffffffff1690508015611bb6576040517fb9ef083000000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff878116600483015282169063b9ef083090602401602060405180830381865afa158015611b73573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611b979190614046565b611bb3906fffffffffffffffffffffffffffffffff16846142f2565b92505b50600101611ac2565b505f808267ffffffffffffffff811115611bdb57611bdb613d8f565b604051908082528060200260200182016040528015611c5857816020015b6040805160c0810182525f8082526020808301829052928201819052606082018190526080820181905260a082015282527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff909201910181611bf95790505b506006546040517f3c59331200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff89811660048301529293505f9290911690633c593312906024015f60405180830381865afa158015611ccb573d5f803e3d5ffd5b505050506040513d5f823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052611d1091908101906141d5565b6060015190505f5b8151811015611ee0575f828281518110611d3457611d34613fde565b602002602001015190505f8815611e10576006546040830151606084015173ffffffffffffffffffffffffffffffffffffffff90921691630c8d01e69190611d7d90429061430b565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b168152600f9290920b60048301526fffffffffffffffffffffffffffffffff166024820152604401602060405180830381865afa158015611de9573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611e0d919061400b565b90505b6040518060c00160405280835f0151815260200183602001516fffffffffffffffffffffffffffffffff1681526020018360400151600f0b815260200183606001516fffffffffffffffffffffffffffffffff16815260200160035f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200182815250858781518110611ebc57611ebc613fde565b602002602001018190525085611ed190614333565b95508260010192505050611d18565b505060045473ffffffffffffffffffffffffffffffffffffffff16156121a1576007546040517f3c59331200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff88811660048301525f921690633c593312906024015f60405180830381865afa158015611f6d573d5f803e3d5ffd5b505050506040513d5f823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052611fb291908101906141d5565b6060015190505f5b815181101561219e575f828281518110611fd657611fd6613fde565b602002602001015190504281606001516fffffffffffffffffffffffffffffffff161115612195575f88156120d0576007546040830151606084015173ffffffffffffffffffffffffffffffffffffffff90921691630e5f6d5d919061203d90429061430b565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b168152600f9290920b60048301526fffffffffffffffffffffffffffffffff166024820152604401602060405180830381865afa1580156120a9573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906120cd919061400b565b90505b6040518060c00160405280835f0151815260200183602001516fffffffffffffffffffffffffffffffff1681526020018360400151600f0b815260200183606001516fffffffffffffffffffffffffffffffff16815260200160045f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281525085878151811061217c5761217c613fde565b60200260200101819052508561219190614333565b9550505b50600101611fba565b50505b60055473ffffffffffffffffffffffffffffffffffffffff16158015906121df575060085473ffffffffffffffffffffffffffffffffffffffff1615155b156123b4576005546040517fcbf9fe5f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff88811660048301525f92169063cbf9fe5f90602401606060405180830381865afa158015612252573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906122769190614381565b905042816020015167ffffffffffffffff1611156123b2575f861561232a576005546040517f70a0823100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8a81166004830152909116906370a0823190602401602060405180830381865afa158015612303573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612327919061400b565b90505b6040805160c0810182525f8082526020808301919091528451600f0b928201929092529083015167ffffffffffffffff16606082015260055473ffffffffffffffffffffffffffffffffffffffff16608082015260a08101829052835184908690811061239957612399613fde565b6020026020010181905250836123ae90614333565b9350505b505b5f5b600a5481101561273b575f600a82815481106123d4576123d4613fde565b5f9182526020909120015473ffffffffffffffffffffffffffffffffffffffff1690508015612732575f8173ffffffffffffffffffffffffffffffffffffffff166366d6bff96040518163ffffffff1660e01b8152600401602060405180830381865afa158015612447573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061246b919061406a565b6040517f3c59331200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8b811660048301529190911690633c593312906024015f60405180830381865afa1580156124d6573d5f803e3d5ffd5b505050506040513d5f823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016820160405261251b91908101906141d5565b6060015190505f5b815181101561272f575f82828151811061253f5761253f613fde565b602002602001015190505f8a15612680578473ffffffffffffffffffffffffffffffffffffffff166366d6bff96040518163ffffffff1660e01b8152600401602060405180830381865afa158015612599573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906125bd919061406a565b73ffffffffffffffffffffffffffffffffffffffff16630c8d01e683604001514285606001516125ed919061430b565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b168152600f9290920b60048301526fffffffffffffffffffffffffffffffff166024820152604401602060405180830381865afa158015612659573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061267d919061400b565b90505b6040518060c00160405280835f0151815260200183602001516fffffffffffffffffffffffffffffffff1681526020018360400151600f0b815260200183606001516fffffffffffffffffffffffffffffffff1681526020018673ffffffffffffffffffffffffffffffffffffffff1681526020018281525087898151811061270b5761270b613fde565b60200260200101819052508761272090614333565b97508260010192505050612523565b50505b506001016123b6565b508167ffffffffffffffff81111561275557612755613d8f565b6040519080825280602002602001820160405280156127d257816020015b6040805160c0810182525f8082526020808301829052928201819052606082018190526080820181905260a082015282527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9092019101816127735790505b5093505f5b845181101561281f578181815181106127f2576127f2613fde565b602002602001015185828151811061280c5761280c613fde565b60209081029190910101526001016127d7565b5050505092915050565b5f5473ffffffffffffffffffffffffffffffffffffffff163314801590612868575060095473ffffffffffffffffffffffffffffffffffffffff163314155b1561289f576040517ffee4291a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f546128c390839073ffffffffffffffffffffffffffffffffffffffff1683613b7e565b6040805173ffffffffffffffffffffffffffffffffffffffff84168152602081018390527f55350610fe57096d8c0ffa30beede987326bccfcb0b4415804164d0dd50ce8b1910160405180910390a15050565b6003546040517fb9ef083000000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff83811660048301526060925f9291169063b9ef083090602401602060405180830381865afa158015612988573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906129ac9190614046565b6004546fffffffffffffffffffffffffffffffff91909116915073ffffffffffffffffffffffffffffffffffffffff1615612a9457600480546040517fb9ef083000000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8681169382019390935291169063b9ef083090602401602060405180830381865afa158015612a51573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612a759190614046565b612a91906fffffffffffffffffffffffffffffffff16826142f2565b90505b60055473ffffffffffffffffffffffffffffffffffffffff1615801590612ad2575060085473ffffffffffffffffffffffffffffffffffffffff1615155b15612ae557612ae26001826142f2565b90505b5f5b600a54811015612be4575f600a8281548110612b0557612b05613fde565b5f9182526020909120015473ffffffffffffffffffffffffffffffffffffffff1690508015612bdb576040517fb9ef083000000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff868116600483015282169063b9ef083090602401602060405180830381865afa158015612b98573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612bbc9190614046565b612bd8906fffffffffffffffffffffffffffffffff16846142f2565b92505b50600101612ae7565b505f808267ffffffffffffffff811115612c0057612c00613d8f565b604051908082528060200260200182016040528015612c7d57816020015b6040805160c0810182525f8082526020808301829052928201819052606082018190526080820181905260a082015282527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff909201910181612c1e5790505b506006546040517f3c59331200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff88811660048301529293505f9290911690633c593312906024015f60405180830381865afa158015612cf0573d5f803e3d5ffd5b505050506040513d5f823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052612d3591908101906141d5565b6080015190505f5b8151811015612e2f575f828281518110612d5957612d59613fde565b602002602001015190506040518060c00160405280825f0151815260200182602001516fffffffffffffffffffffffffffffffff1681526020018260400151600f0b815260200182606001516fffffffffffffffffffffffffffffffff16815260200160035f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020015f815250848681518110612e0f57612e0f613fde565b602002602001018190525084612e2490614333565b945050600101612d3d565b505060045473ffffffffffffffffffffffffffffffffffffffff1615612ffe576007546040517f3c59331200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff87811660048301525f921690633c593312906024015f60405180830381865afa158015612ebc573d5f803e3d5ffd5b505050506040513d5f823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052612f0191908101906141d5565b6080015190505f5b8151811015612ffb575f828281518110612f2557612f25613fde565b602002602001015190506040518060c00160405280825f0151815260200182602001516fffffffffffffffffffffffffffffffff1681526020018260400151600f0b815260200182606001516fffffffffffffffffffffffffffffffff16815260200160045f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020015f815250848681518110612fdb57612fdb613fde565b602002602001018190525084612ff090614333565b945050600101612f09565b50505b60055473ffffffffffffffffffffffffffffffffffffffff161580159061303c575060085473ffffffffffffffffffffffffffffffffffffffff1615155b15613173576005546040517fcbf9fe5f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff87811660048301525f92169063cbf9fe5f90602401606060405180830381865afa1580156130af573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906130d39190614381565b905042816020015167ffffffffffffffff1611613171576040805160c0810182525f80825260208083018290528451600f0b938301939093529183015167ffffffffffffffff16606082015260055473ffffffffffffffffffffffffffffffffffffffff16608082015260a0810191909152825183908590811061315957613159613fde565b60200260200101819052508261316e90614333565b92505b505b5f5b600a548110156133bf575f600a828154811061319357613193613fde565b5f9182526020909120015473ffffffffffffffffffffffffffffffffffffffff16905080156133b6575f8173ffffffffffffffffffffffffffffffffffffffff166366d6bff96040518163ffffffff1660e01b8152600401602060405180830381865afa158015613206573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061322a919061406a565b6040517f3c59331200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8a811660048301529190911690633c593312906024015f60405180830381865afa158015613295573d5f803e3d5ffd5b505050506040513d5f823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526132da91908101906141d5565b6080015190505f5b81518110156133b3575f8282815181106132fe576132fe613fde565b602002602001015190506040518060c00160405280825f0151815260200182602001516fffffffffffffffffffffffffffffffff1681526020018260400151600f0b815260200182606001516fffffffffffffffffffffffffffffffff1681526020018573ffffffffffffffffffffffffffffffffffffffff1681526020015f81525086888151811061339357613393613fde565b6020026020010181905250866133a890614333565b9650506001016132e2565b50505b50600101613175565b508167ffffffffffffffff8111156133d9576133d9613d8f565b60405190808252806020026020018201604052801561345657816020015b6040805160c0810182525f8082526020808301829052928201819052606082018190526080820181905260a082015282527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9092019101816133f75790505b5093505f5b84518110156134a35781818151811061347657613476613fde565b602002602001015185828151811061349057613490613fde565b602090810291909101015260010161345b565b50505050919050565b5f5473ffffffffffffffffffffffffffffffffffffffff1633148015906134eb575060095473ffffffffffffffffffffffffffffffffffffffff163314155b15613522576040517ffee4291a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600980547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b6003546040517f70a0823100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff83811660048301525f9216906370a0823190602401602060405180830381865afa1580156135d7573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906135fb919061400b565b60045490915073ffffffffffffffffffffffffffffffffffffffff16156136bd57600480546040517f70a0823100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff858116938201939093529116906370a0823190602401602060405180830381865afa15801561368c573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906136b0919061400b565b6136ba90826142f2565b90505b60055473ffffffffffffffffffffffffffffffffffffffff16158015906136fb575060085473ffffffffffffffffffffffffffffffffffffffff1615155b1561379f576005546040517f70a0823100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8481166004830152909116906370a0823190602401602060405180830381865afa15801561376e573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190613792919061400b565b61379c90826142f2565b90505b5f5b600a5481101561388c575f600a82815481106137bf576137bf613fde565b5f9182526020909120015473ffffffffffffffffffffffffffffffffffffffff1690508015613883576040517f70a0823100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff85811660048301528216906370a0823190602401602060405180830381865afa158015613852573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190613876919061400b565b61388090846142f2565b92505b506001016137a1565b50919050565b5f8061389c611491565b6080015192915050565b5f5473ffffffffffffffffffffffffffffffffffffffff1633148015906138e5575060095473ffffffffffffffffffffffffffffffffffffffff163314155b1561391c576040517ffee4291a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116613999576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f5a65726f206164647265737320646574656374656400000000000000000000006044820152606401610581565b73ffffffffffffffffffffffffffffffffffffffff81165f908152600b602052604090205460ff161515600114613a2c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f41646472657373206e6f6e6578697374656e74000000000000000000000000006044820152606401610581565b73ffffffffffffffffffffffffffffffffffffffff81165f908152600b6020526040812080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001690555b600a54811015613b37578173ffffffffffffffffffffffffffffffffffffffff16600a8281548110613aab57613aab613fde565b5f9182526020909120015473ffffffffffffffffffffffffffffffffffffffff1603613b2f575f600a8281548110613ae557613ae5613fde565b905f5260205f20015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550613b37565b600101613a77565b5060405173ffffffffffffffffffffffffffffffffffffffff821681527ff3517f912cde760e82811897047177df419c7aa16326d5710e6b425a8a7d10359060200161113b565b6040805173ffffffffffffffffffffffffffffffffffffffff8481166024830152604480830185905283518084039091018152606490920183526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb0000000000000000000000000000000000000000000000000000000017905291515f92839290871691613c1491906143ed565b5f604051808303815f865af19150503d805f8114613c4d576040519150601f19603f3d011682016040523d82523d5f602084013e613c52565b606091505b5091509150811580613c805750805115801590613c80575080806020019051810190613c7e9190614403565b155b15613cb7576040517f19a9708500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050505050565b5f60c08284031215613cce575f80fd5b8260c08301111561388c575f80fd5b73ffffffffffffffffffffffffffffffffffffffff81168114610b31575f80fd5b5f60208284031215613d0e575f80fd5b8135613d1981613cdd565b9392505050565b602080825282518282018190525f918401906040840190835b81811015613d6d57835173ffffffffffffffffffffffffffffffffffffffff16835260209384019390920191600101613d39565b509095945050505050565b5f60208284031215613d88575f80fd5b5035919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b60405160c0810167ffffffffffffffff81118282101715613ddf57613ddf613d8f565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715613e2c57613e2c613d8f565b604052919050565b5f805f6101008486031215613e47575f80fd5b8335613e5281613cdd565b92506020840135613e6281613cdd565b9150605f84018513613e72575f80fd5b613e7c60c0613de5565b80610100860187811115613e8e575f80fd5b604087015b81811015613eb4578035613ea681613cdd565b845260209384019301613e93565b505080925050509250925092565b8015158114610b31575f80fd5b5f8060408385031215613ee0575f80fd5b8235613eeb81613cdd565b91506020830135613efb81613ec2565b809150509250929050565b602080825282518282018190525f918401906040840190835b81811015613d6d578351805184526fffffffffffffffffffffffffffffffff60208201511660208501526040810151600f0b60408501526fffffffffffffffffffffffffffffffff606082015116606085015273ffffffffffffffffffffffffffffffffffffffff608082015116608085015260a081015160a08501525060c083019250602084019350600181019050613f1f565b5f8060408385031215613fc5575f80fd5b8235613fd081613cdd565b946020939093013593505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b5f6020828403121561401b575f80fd5b5051919050565b80516fffffffffffffffffffffffffffffffff81168114614041575f80fd5b919050565b5f60208284031215614056575f80fd5b613d1982614022565b805161404181613cdd565b5f6020828403121561407a575f80fd5b8151613d1981613cdd565b8051600f81900b8114614041575f80fd5b5f82601f8301126140a5575f80fd5b8151602083015f8067ffffffffffffffff8411156140c5576140c5613d8f565b60208460051b0190506140d781613de5565b84815260079490941b83019391505060208101868411156140f6575f80fd5b83831015614180575f6080848903121561410e575f80fd5b6040516080810167ffffffffffffffff8111828210171561413157614131613d8f565b6040528451808252915061414760208601614022565b602082015261415860408601614085565b604082015261416960608601614022565b6060820152825250608092909201916020016140f6565b5095945050505050565b5f82601f830112614199575f80fd5b6141a36060613de5565b8060608401858111156141b4575f80fd5b845b81811015613d6d576141c781614085565b8452602093840193016141b6565b5f602082840312156141e5575f80fd5b815167ffffffffffffffff8111156141fb575f80fd5b8201610100818503121561420d575f80fd5b614215613dbc565b61421e8261405f565b815260208281015190820152604082015167ffffffffffffffff811115614243575f80fd5b61424f86828501614096565b604083015250606082015167ffffffffffffffff81111561426e575f80fd5b61427a86828501614096565b606083015250608082015167ffffffffffffffff811115614299575f80fd5b6142a586828501614096565b6080830152506142b88560a0840161418a565b60a0820152949350505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b80820180821115614305576143056142c5565b92915050565b6fffffffffffffffffffffffffffffffff8281168282160390811115614305576143056142c5565b5f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203614363576143636142c5565b5060010190565b805167ffffffffffffffff81168114614041575f80fd5b5f6060828403128015614392575f80fd5b506040516060810167ffffffffffffffff811182821017156143b6576143b6613d8f565b6040526143c283614022565b81526143d06020840161436a565b60208201526143e16040840161436a565b60408201529392505050565b5f82518060208501845e5f920191825250919050565b5f60208284031215614413575f80fd5b8151613d1981613ec256fea2646970667358221220906e77c6f61b3057feae5009f729232e2975ab0fb6ae39d9a4d084df7d210dc164736f6c634300081a0033
Deployed Bytecode Sourcemap
156667:31874:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;185171:1298;;;;;;:::i;:::-;;:::i;:::-;;182718:784;;;;;;:::i;:::-;;:::i;157588:56::-;;;;;;;;;;;;892:42:1;880:55;;;862:74;;850:2;835:18;157588:56:0;;;;;;;;101035:141;;;;;;:::i;:::-;;:::i;157085:23::-;;;;;;;;;157978:47;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;1363:14:1;;1356:22;1338:41;;1326:2;1311:18;157978:47:0;1198:187:1;157746:30:0;;;;;;;;;165354:134;;;:::i;:::-;;;;;;;:::i;100886:29::-;;;;;;;;;157852:35;;;;;;:::i;:::-;;:::i;160111:1089::-;;;;;;:::i;:::-;;:::i;162867:1836::-;;;:::i;:::-;;;;;;4509:4:1;4551:3;4540:9;4536:19;4528:27;;4588:6;4582:13;4571:9;4564:32;4652:4;4644:6;4640:17;4634:24;4627:4;4616:9;4612:20;4605:54;4715:4;4707:6;4703:17;4697:24;4690:4;4679:9;4675:20;4668:54;4778:4;4770:6;4766:17;4760:24;4753:4;4742:9;4738:20;4731:54;4841:4;4833:6;4829:17;4823:24;4816:4;4805:9;4801:20;4794:54;4333:521;;;;;157159:29:0;;;;;;;;;101184:354;;;:::i;166037:8890::-;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;184644:306::-;;;;;;:::i;:::-;;:::i;100859:20::-;;;;;;;;;175270:6914;;;;;;:::i;:::-;;:::i;186576:114::-;;;;;;:::i;:::-;;:::i;165603:127::-;165697:18;:25;165603:127;;;7294:25:1;;;7282:2;7267:18;165603:127:0;7148:177:1;161606:1006:0;;;;;;:::i;:::-;;:::i;157276:23::-;;;;;;;;;165016:231;;;:::i;183708:698::-;;;;;;:::i;:::-;;:::i;157363:33::-;;;;;;;;;157471;;;;;;;;;185171:1298;159411:5;;;;159397:10;:19;;;;:52;;-1:-1:-1;159434:15:0;;;;159420:10;:29;;159397:52;159393:85;;;159458:20;;;;;;;;;;;;;;159393:85;185373:1:::1;185346:15;;::::0;::::1;:12:::0;:15:::1;:::i;:::-;:29;;::::0;185338:63:::1;;;::::0;::::1;::::0;;8481:2:1;185338:63:0::1;::::0;::::1;8463:21:1::0;8520:2;8500:18;;;8493:30;8559:23;8539:18;;;8532:51;8600:18;;185338:63:0::1;;;;;;;;;185447:1;185420:15;::::0;;;::::1;::::0;::::1;;:::i;:::-;:29;;::::0;185412:68:::1;;;::::0;::::1;::::0;;8831:2:1;185412:68:0::1;::::0;::::1;8813:21:1::0;8870:2;8850:18;;;8843:30;8909:28;8889:18;;;8882:56;8955:18;;185412:68:0::1;8629:350:1::0;185412:68:0::1;185526:1;185499:15;::::0;;;;;::::1;;:::i;:::-;:29;;::::0;185491:67:::1;;;::::0;::::1;::::0;;9186:2:1;185491:67:0::1;::::0;::::1;9168:21:1::0;9225:2;9205:18;;;9198:30;9264:27;9244:18;;;9237:55;9309:18;;185491:67:0::1;8984:349:1::0;185491:67:0::1;185604:1;185577:15;::::0;;;;;::::1;;:::i;:::-;:29;;::::0;185569:72:::1;;;::::0;::::1;::::0;;9540:2:1;185569:72:0::1;::::0;::::1;9522:21:1::0;9579:2;9559:18;;;9552:30;9618:32;9598:18;;;9591:60;9668:18;;185569:72:0::1;9338:354:1::0;185569:72:0::1;185687:1;185660:15;::::0;;;;;::::1;;:::i;:::-;:29;;::::0;185652:64:::1;;;::::0;::::1;::::0;;9899:2:1;185652:64:0::1;::::0;::::1;9881:21:1::0;9938:2;9918:18;;;9911:30;9977:24;9957:18;;;9950:52;10019:18;;185652:64:0::1;9697:346:1::0;185652:64:0::1;185762:1;185735:15;::::0;;;;;::::1;;:::i;:::-;:29;;::::0;185727:81:::1;;;::::0;::::1;::::0;;10250:2:1;185727:81:0::1;::::0;::::1;10232:21:1::0;10289:2;10269:18;;;10262:30;10328:34;10308:18;;;10301:62;10399:9;10379:18;;;10372:37;10426:19;;185727:81:0::1;10048:403:1::0;185727:81:0::1;185877:15;;::::0;::::1;:12:::0;:15:::1;:::i;:::-;185858:5;:35:::0;;;::::1;;::::0;;;::::1;::::0;;;::::1;::::0;;185933:15:::1;::::0;;;::::1;::::0;::::1;;:::i;:::-;185904:10;:45:::0;;;::::1;;::::0;;;::::1;::::0;;;::::1;::::0;;-1:-1:-1;185991:15:0::1;::::0;;;;;::::1;;:::i;:::-;:29;;;;185990:64;;;;-1:-1:-1::0;186052:1:0::1;186025:15;::::0;;;;;::::1;;:::i;:::-;:29;;;;185990:64;185986:198;;;186096:15;::::0;;;;;::::1;;:::i;:::-;186071:10;:41:::0;;;::::1;;::::0;;;::::1;::::0;;;::::1;::::0;;186156:15:::1;::::0;;;;;::::1;;:::i;:::-;186127:10;:45:::0;;;::::1;;::::0;;;::::1;::::0;;;::::1;::::0;;185986:198:::1;186277:1;186250:15;::::0;;;;;::::1;;:::i;:::-;:29;;;;186249:66;;;;-1:-1:-1::0;186312:1:0::1;186285:15;::::0;;;;;::::1;;:::i;:::-;:29;;;;186249:66;186245:217;;;186351:15;::::0;;;;;::::1;;:::i;:::-;186332:7;:35:::0;;;::::1;;::::0;;;::::1;::::0;;;::::1;::::0;;186434:15:::1;::::0;;;;;::::1;;:::i;:::-;186382:24;:68:::0;;;::::1;;::::0;;;::::1;::::0;;;::::1;::::0;;186245:217:::1;185171:1298:::0;:::o;182718:784::-;159411:5;;;;159397:10;:19;;;;:52;;-1:-1:-1;159434:15:0;;;;159420:10;:29;;159397:52;159393:85;;;159458:20;;;;;;;;;;;;;;159393:85;182802:19:::1;::::0;::::1;182794:53;;;::::0;::::1;::::0;;10658:2:1;182794:53:0::1;::::0;::::1;10640:21:1::0;10697:2;10677:18;;;10670:30;10736:23;10716:18;;;10709:51;10777:18;;182794:53:0::1;10456:345:1::0;182794:53:0::1;182972:5;182961:29;;;:31;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;183003:39:0::1;::::0;;;;183039:1:::1;183003:39;::::0;::::1;862:74:1::0;183003:27:0::1;::::0;::::1;::::0;::::1;::::0;835:18:1;;183003:39:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;183053:38:0::1;::::0;;;;183088:1:::1;183053:38;::::0;::::1;862:74:1::0;183053:26:0::1;::::0;::::1;::::0;::::1;::::0;835:18:1;;183053:38:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;183129:5;183118:28;;;:30;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;183102:83;::::0;;;;183182:1:::1;183102:83;::::0;::::1;862:74:1::0;183102:71:0::1;::::0;;;::::1;::::0;::::1;::::0;835:18:1;;183102:83:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;::::0;;::::1;::::0;::::1;::::0;::::1;;::::0;::::1;::::0;;;::::1;::::0;::::1;:::i;:::-;;183223:5;183212:28;;;:30;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;183196:91;::::0;;;;183273:4:::1;183196:91;::::0;::::1;15743:41:1::0;183279:7:0::1;15800:18:1::0;;;15793:75;183196:76:0::1;::::0;;;::::1;::::0;::::1;::::0;15716:18:1;;183196:91:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;183308:22:0::1;::::0;::::1;;::::0;;;:15:::1;:22;::::0;;;;;::::1;;:31;183300:66;;;::::0;::::1;::::0;;16081:2:1;183300:66:0::1;::::0;::::1;16063:21:1::0;16120:2;16100:18;;;16093:30;16159:24;16139:18;;;16132:52;16201:18;;183300:66:0::1;15879:346:1::0;183300:66:0::1;183377:22;::::0;::::1;;::::0;;;:15:::1;:22;::::0;;;;;;;:29;;;::::1;183402:4;183377:29:::0;;::::1;::::0;;;183417:18:::1;:30:::0;;;;::::1;::::0;;;;;;;;::::1;::::0;;;::::1;::::0;::::1;::::0;;183465:29;;862:74:1;;;183465:29:0::1;::::0;835:18:1;183465:29:0::1;;;;;;;;182718:784:::0;:::o;101035:141::-;101689:5;;;;101675:10;:19;101671:43;;101703:11;;;;;;;;;;;;;;101671:43;101107:14:::1;:23:::0;;;::::1;;::::0;::::1;::::0;;::::1;::::0;;;101146:22:::1;::::0;862:74:1;;;101146:22:0::1;::::0;850:2:1;835:18;101146:22:0::1;683:259:1::0;165354:134:0;165415:27;165462:18;165455:25;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;165354:134;:::o;157852:35::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;157852:35:0;:::o;160111:1089::-;160320:14;;;;160316:45;;;160343:18;;;;;;;;;;;;;;160316:45;160408:5;:14;;;;;;;;;;;;;;160466:15;:34;;;;;;;;;;;160570:15;;160551:5;:35;;;;;;;;;;;;;160570:15;160626;;;-1:-1:-1;160597:45:0;;;;;;;;;;;160702:15;;;;:29;;;;;160701:66;;-1:-1:-1;160737:15:0;;;;:29;;;;160701:66;160697:200;;;160809:15;;;;160784:10;:41;;;;;;;;;;;;;;160869:15;;;;160840:10;:45;;;;;;;;;;;160697:200;160981:15;;;;:29;;;;;;160980:66;;-1:-1:-1;161016:15:0;;;;:29;;;;160980:66;160976:217;;;161082:15;;;;161063:7;:35;;;;;;;;;;;;;;161165:15;;;;161113:24;:68;;;;;;;;;;;160976:217;160111:1089;;;:::o;162867:1836::-;162935:42;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;162935:42:0;163135:5;;;;;;;;;;;:17;;;:19;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;163106:48;;;163165:22;;;:51;163374:10;;163366:33;163374:10;163366:33;163362:285;;163446:10;;;:24;;;;;;;;:10;;;;;:22;;:24;;;;;;;;;;;;:10;:24;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;163416:27;;;:54;;;163485:22;;;:53;;;;163416:54;;163485:53;:::i;:::-;;;-1:-1:-1;163362:285:0;163757:7;;163749:30;163757:7;163749:30;;;;163748:85;;-1:-1:-1;163793:24:0;;163785:47;163793:24;163785:47;;163748:85;163744:356;;;163877:24;;;;;;;;;;;:36;;;:38;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;163850:24;;;:65;;;163930:22;;;:50;;;;163850:65;;163930:50;:::i;:::-;;;-1:-1:-1;163744:356:0;164172:9;164167:529;164187:18;:25;164183:29;;164167:529;;;164231:15;164249:18;164268:1;164249:21;;;;;;;;:::i;:::-;;;;;;;;;;;;;;-1:-1:-1;164289:21:0;;164285:336;;164331:19;164364:7;164353:31;;;:33;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;164331:55;;164438:11;164405;:29;;:44;;;;;;;:::i;:::-;;;-1:-1:-1;164468:22:0;;;:37;;164494:11;;164468:22;:37;;164494:11;;164468:37;:::i;:::-;;;-1:-1:-1;;164285:336:0;-1:-1:-1;164666:3:0;;164167:529;;;;162867:1836;:::o;101184:354::-;101357:14;;;;101343:10;:28;101339:69;;101380:28;;;;;;;;;;;;;;101339:69;101437:5;;;101444:14;101424:35;;;101437:5;;;;16723:74:1;;101444:14:0;;;;16828:2:1;16813:18;;16806:83;101424:35:0;;16696:18:1;101424:35:0;;;;;;;101478:14;;;;101470:22;;;;;;101478:14;;;101470:22;;;;101503:27;;;101184:354::o;166037:8890::-;166442:5;;:24;;;;;:5;880:55:1;;;166442:24:0;;;862:74:1;166158:49:0;;166420:19;;166442:5;;;:14;;835:18:1;;166442:24:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;166526:10;;166420:46;;;;;;-1:-1:-1;166518:33:0;166526:10;166518:33;166514:83;;166568:10;;;:29;;;;;:10;880:55:1;;;166568:29:0;;;862:74:1;;;;166568:10:0;;;:19;;835:18:1;;166568:29:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;166553:44;;;;;;:::i;:::-;;;166514:83;166654:7;;166646:30;166654:7;166646:30;;;;166645:85;;-1:-1:-1;166690:24:0;;166682:47;166690:24;166682:47;;166645:85;166641:179;;;166747:16;166762:1;166747:16;;:::i;:::-;;;166641:179;166924:9;166919:301;166943:18;:25;166939:29;;166919:301;;;166990:15;167008:18;167027:1;167008:21;;;;;;;;:::i;:::-;;;;;;;;;;;;;;-1:-1:-1;167048:21:0;;167044:165;;167155:38;;;;;:28;880:55:1;;;167155:38:0;;;862:74:1;167155:28:0;;;;;835:18:1;;167155:38:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;167140:53;;;;;;:::i;:::-;;;167044:165;-1:-1:-1;166970:3:0;;166919:301;;;;167279:22;167316:48;167397:11;167367:42;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;167367:42:0;;;;;;;;;;;;;;-1:-1:-1;167655:10:0;;:44;;;;;:10;880:55:1;;;167655:44:0;;;862:74:1;167316:93:0;;-1:-1:-1;167596:55:0;;167655:10;;;;:34;;835:18:1;;167655:44:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;167654:76;;;167596:134;;167839:9;167834:1288;167854:24;:31;167850:1;:35;167834:1288;;;167956:61;168020:24;168045:1;168020:27;;;;;;;;:::i;:::-;;;;;;;167956:91;;168167:23;168213:19;168209:276;;;168275:10;;168341:25;;;;168393:22;;;;168275:10;;;;;:39;;168341:25;168393:49;;168426:15;;168393:49;:::i;:::-;168275:190;;;;;;;;;;15772:2:1;15761:22;;;;168275:190:0;;;15743:41:1;15832:34;15820:47;15800:18;;;15793:75;15716:18;;168275:190:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;168257:208;;168209:276;168581:361;;;;;;;;168632:18;:21;;;168581:361;;;;168683:18;:24;;;168581:361;;;;;;168738:18;:25;;;168581:361;;;;;;168791:18;:22;;;168581:361;;;;;;168854:5;;;;;;;;;;;168581:361;;;;;;168907:15;168581:361;;;168547:15;168563:14;168547:31;;;;;;;;:::i;:::-;;;;;;:395;;;;169014:16;;;;:::i;:::-;;;169084:3;;;;;167889:1233;;167834:1288;;;-1:-1:-1;;169230:10:0;;169222:33;169230:10;169222:33;169218:1852;;169411:10;;:44;;;;;:10;880:55:1;;;169411:44:0;;;862:74:1;169319:70:0;;169411:10;;:34;;835:18:1;;169411:44:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;169392:90;;;169319:163;;169589:9;169584:1475;169604:25;:32;169600:1;:36;169584:1475;;;169707:56;169766:25;169792:1;169766:28;;;;;;;;:::i;:::-;;;;;;;169707:87;;169881:15;169861:13;:17;;;:35;;;169857:1111;;;170024:23;170074:19;170070:286;;;170140:10;;170210:20;;;;170261:17;;;;170140:10;;;;;:39;;170210:20;170261:44;;170289:15;;170261:44;:::i;:::-;170140:192;;;;;;;;;;15772:2:1;15761:22;;;;170140:192:0;;;15743:41:1;15832:34;15820:47;15800:18;;;15793:75;15716:18;;170140:192:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;170122:210;;170070:286;170478:374;;;;;;;;170533:13;:16;;;170478:374;;;;170583:13;:19;;;170478:374;;;;;;170637:13;:20;;;170478:374;;;;;;170689:13;:17;;;170478:374;;;;;;170751:10;;;;;;;;;;;170478:374;;;;;;170813:15;170478:374;;;170444:15;170460:14;170444:31;;;;;;;;:::i;:::-;;;;;;:408;;;;170932:16;;;;:::i;:::-;;;169898:1070;169857:1111;-1:-1:-1;171021:3:0;;169584:1475;;;;169257:1813;169218:1852;171164:7;;171156:30;171164:7;171156:30;;;;171155:85;;-1:-1:-1;171200:24:0;;171192:47;171200:24;171192:47;;171155:85;171151:1221;;;171344:7;;:24;;;;;:7;880:55:1;;;171344:24:0;;;862:74:1;171295:46:0;;171344:7;;:14;;835:18:1;;171344:24:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;171295:73;;171547:15;171524:16;:20;;;:38;;;171520:841;;;171682:23;171728:19;171724:113;;;171790:7;;:27;;;;;:7;880:55:1;;;171790:27:0;;;862:74:1;171790:7:0;;;;:17;;835:18:1;;171790:27:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;171772:45;;171724:113;171933:324;;;;;;;;-1:-1:-1;171933:324:0;;;;;;;;;;;172054:23;;171933:324;;;;;;;;;172106:20;;;;171933:324;;;;;;172167:7;;;;171933:324;;;;;;;;;;171899:31;;:15;;171915:14;;171899:31;;;;;;:::i;:::-;;;;;;:358;;;;172329:16;;;;:::i;:::-;;;171564:797;171520:841;171242:1130;171151:1221;172494:9;172489:2055;172509:18;:25;172505:29;;172489:2055;;;172553:15;172571:18;172590:1;172571:21;;;;;;;;:::i;:::-;;;;;;;;;;;;;;-1:-1:-1;172611:21:0;;172607:1862;;172694:55;172802:7;172791:30;;;:32;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;172775:83;;;;;:73;880:55:1;;;172775:83:0;;;862:74:1;172775:73:0;;;;;;;835:18:1;;172775:83:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;172752:137;;;172694:195;;172999:9;172994:1460;173014:24;:31;173010:1;:35;172994:1460;;;173124:60;173187:24;173212:1;173187:27;;;;;;;;:::i;:::-;;;;;;;173124:90;;173342:23;173392:19;173388:375;;;173485:7;173474:30;;;:32;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;173458:108;;;173601:17;:24;;;173692:15;173660:17;:21;;;:48;;;;:::i;:::-;173458:281;;;;;;;;;;15772:2:1;15761:22;;;;173458:281:0;;;15743:41:1;15832:34;15820:47;15800:18;;;15793:75;15716:18;;173458:281:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;173440:299;;173388:375;173872:378;;;;;;;;173927:17;:20;;;173872:378;;;;173981:17;:23;;;173872:378;;;;;;174039:17;:24;;;173872:378;;;;;;174095:17;:21;;;173872:378;;;;;;174153:7;173872:378;;;;;;174211:15;173872:378;;;173838:15;173854:14;173838:31;;;;;;;;:::i;:::-;;;;;;:412;;;;174330:16;;;;:::i;:::-;;;174408:3;;;;;173049:1405;;172994:1460;;;;172634:1835;172607:1862;-1:-1:-1;174514:3:0;;172489:2055;;;;174680:14;174650:45;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;174650:45:0;;;;;;;;;;;;;;;174631:64;;174747:9;174742:178;174762:16;:23;174758:1;:27;174742:178;;;174826:15;174842:1;174826:18;;;;;;;;:::i;:::-;;;;;;;174804:16;174821:1;174804:19;;;;;;;;:::i;:::-;;;;;;;;;;:40;174890:3;;174742:178;;;;166209:8718;;;166037:8890;;;;:::o;184644:306::-;159411:5;;;;159397:10;:19;;;;:52;;-1:-1:-1;159434:15:0;;;;159420:10;:29;;159397:52;159393:85;;;159458:20;;;;;;;;;;;;;;159393:85;184863:5:::1;::::0;184820:63:::1;::::0;184848:13;;184863:5:::1;;184870:12:::0;184820:27:::1;:63::i;:::-;184899:43;::::0;;20123:42:1;20111:55;;20093:74;;20198:2;20183:18;;20176:34;;;184899:43:0::1;::::0;20066:18:1;184899:43:0::1;;;;;;;184644:306:::0;;:::o;175270:6914::-;175619:5;;:24;;;;;:5;880:55:1;;;175619:24:0;;;862:74:1;175337:46:0;;175597:19;;175619:5;;;:14;;835:18:1;;175619:24:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;175703:10;;175597:46;;;;;;-1:-1:-1;175695:33:0;175703:10;175695:33;175691:83;;175745:10;;;:29;;;;;:10;880:55:1;;;175745:29:0;;;862:74:1;;;;175745:10:0;;;:19;;835:18:1;;175745:29:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;175730:44;;;;;;:::i;:::-;;;175691:83;175831:7;;175823:30;175831:7;175823:30;;;;175822:85;;-1:-1:-1;175867:24:0;;175859:47;175867:24;175859:47;;175822:85;175818:179;;;175924:16;175939:1;175924:16;;:::i;:::-;;;175818:179;176101:9;176096:301;176120:18;:25;176116:29;;176096:301;;;176167:15;176185:18;176204:1;176185:21;;;;;;;;:::i;:::-;;;;;;;;;;;;;;-1:-1:-1;176225:21:0;;176221:165;;176332:38;;;;;:28;880:55:1;;;176332:38:0;;;862:74:1;176332:28:0;;;;;835:18:1;;176332:38:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;176317:53;;;;;;:::i;:::-;;;176221:165;-1:-1:-1;176147:3:0;;176096:301;;;;176456:23;176494:49;176576:11;176546:42;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;176546:42:0;;;;;;;;;;;;;;-1:-1:-1;176834:10:0;;:44;;;;;:10;880:55:1;;;176834:44:0;;;862:74:1;176494:94:0;;-1:-1:-1;176775:55:0;;176834:10;;;;:34;;835:18:1;;176834:44:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;176833:77;;;176775:135;;177019:9;177014:841;177034:24;:31;177030:1;:35;177014:841;;;177136:61;177200:24;177225:1;177200:27;;;;;;;;:::i;:::-;;;;;;;177136:91;;177326:347;;;;;;;;177377:18;:21;;;177326:347;;;;177428:18;:24;;;177326:347;;;;;;177483:18;:25;;;177326:347;;;;;;177536:18;:22;;;177326:347;;;;;;177599:5;;;;;;;;;;;177326:347;;;;;;177652:1;177326:347;;;177290:16;177307:15;177290:33;;;;;;;;:::i;:::-;;;;;;:383;;;;177746:17;;;;:::i;:::-;;-1:-1:-1;;177817:3:0;;177014:841;;;-1:-1:-1;;177963:10:0;;177955:33;177963:10;177955:33;177951:1219;;178144:10;;:44;;;;;:10;880:55:1;;;178144:44:0;;;862:74:1;178052:70:0;;178144:10;;:34;;835:18:1;;178144:44:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;178125:91;;;178052:164;;178323:9;178318:841;178338:25;:32;178334:1;:36;178318:841;;;178441:56;178500:25;178526:1;178500:28;;;;;;;;:::i;:::-;;;;;;;178441:87;;178645:332;;;;;;;;178696:13;:16;;;178645:332;;;;178742:13;:19;;;178645:332;;;;;;178792:13;:20;;;178645:332;;;;;;178840:13;:17;;;178645:332;;;;;;178898:10;;;;;;;;;;;178645:332;;;;;;178956:1;178645:332;;;178609:16;178626:15;178609:33;;;;;;;;:::i;:::-;;;;;;:368;;;;179050:17;;;;:::i;:::-;;-1:-1:-1;;179121:3:0;;178318:841;;;;177990:1180;177951:1219;179264:7;;179256:30;179264:7;179256:30;;;;179255:85;;-1:-1:-1;179300:24:0;;179292:47;179300:24;179292:47;;179255:85;179251:939;;;179444:7;;:24;;;;;:7;880:55:1;;;179444:24:0;;;862:74:1;179395:46:0;;179444:7;;:14;;835:18:1;;179444:24:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;179395:73;;179649:15;179625:16;:20;;;:39;;;179621:558;;179763:310;;;;;;;;-1:-1:-1;179763:310:0;;;;;;;;;;179884:23;;179763:310;;;;;;;;;179936:20;;;;179763:310;;;;;;179997:7;;;;179763:310;;;;;;;;;;;179727:33;;:16;;179744:15;;179727:33;;;;;;:::i;:::-;;;;;;:346;;;;180146:17;;;;:::i;:::-;;;179621:558;179342:848;179251:939;180312:9;180307:1500;180327:18;:25;180323:29;;180307:1500;;;180371:15;180389:18;180408:1;180389:21;;;;;;;;:::i;:::-;;;;;;;;;;;;;;-1:-1:-1;180429:21:0;;180425:1307;;180513:55;180621:7;180610:30;;;:32;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;180594:83;;;;;:73;880:55:1;;;180594:83:0;;;862:74:1;180594:73:0;;;;;;;835:18:1;;180594:83:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;180571:138;;;180513:196;;180820:9;180815:902;180835:24;:31;180831:1;:35;180815:902;;;180945:60;181008:24;181033:1;181008:27;;;;;;;;:::i;:::-;;;;;;;180945:90;;181147:364;;;;;;;;181202:17;:20;;;181147:364;;;;181256:17;:23;;;181147:364;;;;;;181314:17;:24;;;181147:364;;;;;;181370:17;:21;;;181147:364;;;;;;181428:7;181147:364;;;;;;181486:1;181147:364;;;181111:16;181128:15;181111:33;;;;;;;;:::i;:::-;;;;;;:400;;;;181592:17;;;;:::i;:::-;;-1:-1:-1;;181671:3:0;;180815:902;;;;180452:1280;180425:1307;-1:-1:-1;181777:3:0;;180307:1500;;;;181941:15;181911:46;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;181911:46:0;;;;;;;;;;;;;;;181895:62;;182009:9;182004:173;182024:13;:20;182020:1;:24;182004:173;;;182082:16;182099:1;182082:19;;;;;;;;:::i;:::-;;;;;;;182063:13;182077:1;182063:16;;;;;;;;:::i;:::-;;;;;;;;;;:38;182147:3;;182004:173;;;;175385:6799;;;175270:6914;;;:::o;186576:114::-;159411:5;;;;159397:10;:19;;;;:52;;-1:-1:-1;159434:15:0;;;;159420:10;:29;;159397:52;159393:85;;;159458:20;;;;;;;;;;;;;;159393:85;186652:15:::1;:30:::0;;;::::1;;::::0;;;::::1;::::0;;;::::1;::::0;;186576:114::o;161606:1006::-;161824:5;;:22;;;;;:5;880:55:1;;;161824:22:0;;;862:74:1;161668:16:0;;161824:5;;:15;;835:18:1;;161824:22:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;161917:10;;161813:33;;-1:-1:-1;161909:33:0;161917:10;161909:33;161905:78;;161956:10;;;:27;;;;;:10;880:55:1;;;161956:27:0;;;862:74:1;;;;161956:10:0;;;:20;;835:18:1;;161956:27:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;161944:39;;;;:::i;:::-;;;161905:78;162094:7;;162086:30;162094:7;162086:30;;;;162085:85;;-1:-1:-1;162130:24:0;;162122:47;162130:24;162122:47;;162085:85;162081:154;;;162199:7;;:24;;;;;:7;880:55:1;;;162199:24:0;;;862:74:1;162199:7:0;;;;:17;;835:18:1;;162199:24:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;162187:36;;;;:::i;:::-;;;162081:154;162307:9;162302:303;162322:18;:25;162318:29;;162302:303;;;162366:15;162384:18;162403:1;162384:21;;;;;;;;:::i;:::-;;;;;;;;;;;;;;-1:-1:-1;162424:21:0;;162420:110;;162478:36;;;;;:29;880:55:1;;;162478:36:0;;;862:74:1;162478:29:0;;;;;835:18:1;;162478:36:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;162466:48;;;;:::i;:::-;;;162420:110;-1:-1:-1;162575:3:0;;162302:303;;;;161606:1006;;;:::o;165016:231::-;165076:20;165109:42;165154:37;:35;:37::i;:::-;165217:22;;;;165016:231;-1:-1:-1;;165016:231:0:o;183708:698::-;159411:5;;;;159397:10;:19;;;;:52;;-1:-1:-1;159434:15:0;;;;159420:10;:29;;159397:52;159393:85;;;159458:20;;;;;;;;;;;;;;159393:85;183795:19:::1;::::0;::::1;183787:53;;;::::0;::::1;::::0;;10658:2:1;183787:53:0::1;::::0;::::1;10640:21:1::0;10697:2;10677:18;;;10670:30;10736:23;10716:18;;;10709:51;10777:18;;183787:53:0::1;10456:345:1::0;183787:53:0::1;183859:22;::::0;::::1;;::::0;;;:15:::1;:22;::::0;;;;;::::1;;:30;;:22:::0;:30:::1;183851:62;;;::::0;::::1;::::0;;20423:2:1;183851:62:0::1;::::0;::::1;20405:21:1::0;20462:2;20442:18;;;20435:30;20501:21;20481:18;;;20474:49;20540:18;;183851:62:0::1;20221:343:1::0;183851:62:0::1;183969:22;::::0;::::1;;::::0;;;:15:::1;:22;::::0;;;;183962:29;;;::::1;::::0;;184070:280:::1;184094:18;:25:::0;184090:29;::::1;184070:280;;;184170:5;184145:30;;:18;184164:1;184145:21;;;;;;;;:::i;:::-;;::::0;;;::::1;::::0;;;::::1;::::0;::::1;;:30:::0;184141:198:::1;;184228:1;184196:18;184215:1;184196:21;;;;;;;;:::i;:::-;;;;;;;;;:34;;;;;;;;;;;;;;;;;;184318:5;;184141:198;184121:3;;184070:280;;;-1:-1:-1::0;184367:31:0::1;::::0;892:42:1;880:55;;862:74;;184367:31:0::1;::::0;850:2:1;835:18;184367:31:0::1;683:259:1::0;93339:480:0;93537:45;;;93526:10;20111:55:1;;;93537:45:0;;;20093:74:1;20183:18;;;;20176:34;;;93537:45:0;;;;;;;;;;20066:18:1;;;;93537:45:0;;;;;;;;;;;;;93526:57;;-1:-1:-1;;;;93526:10:0;;;;:57;;93537:45;93526:57;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;93490:93;;;;93714:7;93713:8;:59;;;-1:-1:-1;93726:11:0;;:16;;;;:45;;;93758:4;93747:24;;;;;;;;;;;;:::i;:::-;93746:25;93726:45;93709:102;;;93781:30;;;;;;;;;;;;;;93709:102;93412:407;;93339:480;;;:::o;14:253:1:-;98:6;151:3;139:9;130:7;126:23;122:33;119:53;;;168:1;165;158:12;119:53;208:7;202:3;191:9;187:19;184:32;181:52;;;229:1;226;219:12;272:154;358:42;351:5;347:54;340:5;337:65;327:93;;416:1;413;406:12;431:247;490:6;543:2;531:9;522:7;518:23;514:32;511:52;;;559:1;556;549:12;511:52;598:9;585:23;617:31;642:5;617:31;:::i;:::-;667:5;431:247;-1:-1:-1;;;431:247:1:o;1621:660::-;1811:2;1823:21;;;1893:13;;1796:18;;;1915:22;;;1763:4;;1994:15;;;1968:2;1953:18;;;1763:4;2037:218;2051:6;2048:1;2045:13;2037:218;;;2116:13;;2131:42;2112:62;2100:75;;2204:2;2230:15;;;;2195:12;;;;2073:1;2066:9;2037:218;;;-1:-1:-1;2272:3:1;;1621:660;-1:-1:-1;;;;;1621:660:1:o;2286:226::-;2345:6;2398:2;2386:9;2377:7;2373:23;2369:32;2366:52;;;2414:1;2411;2404:12;2366:52;-1:-1:-1;2459:23:1;;2286:226;-1:-1:-1;2286:226:1:o;2517:184::-;2569:77;2566:1;2559:88;2666:4;2663:1;2656:15;2690:4;2687:1;2680:15;2706:253;2778:2;2772:9;2820:4;2808:17;;2855:18;2840:34;;2876:22;;;2837:62;2834:88;;;2902:18;;:::i;:::-;2938:2;2931:22;2706:253;:::o;2964:334::-;3035:2;3029:9;3091:2;3081:13;;3096:66;3077:86;3065:99;;3194:18;3179:34;;3215:22;;;3176:62;3173:88;;;3241:18;;:::i;:::-;3277:2;3270:22;2964:334;;-1:-1:-1;2964:334:1:o;3303:1025::-;3403:6;3411;3419;3472:3;3460:9;3451:7;3447:23;3443:33;3440:53;;;3489:1;3486;3479:12;3440:53;3528:9;3515:23;3547:31;3572:5;3547:31;:::i;:::-;3597:5;-1:-1:-1;3654:2:1;3639:18;;3626:32;3667:33;3626:32;3667:33;:::i;:::-;3719:7;-1:-1:-1;3764:2:1;3749:18;;3745:32;-1:-1:-1;3735:60:1;;3791:1;3788;3781:12;3735:60;3893:20;3870:3;3893:20;:::i;:::-;3935:3;3976;3965:9;3961:19;4003:7;3995:6;3992:19;3989:39;;;4024:1;4021;4014:12;3989:39;4063:2;4052:9;4048:18;4075:223;4091:6;4086:3;4083:15;4075:223;;;4173:3;4160:17;4190:33;4215:7;4190:33;:::i;:::-;4236:20;;4285:2;4276:12;;;;4108;4075:223;;;4079:3;;4317:5;4307:15;;;;3303:1025;;;;;:::o;5110:118::-;5196:5;5189:13;5182:21;5175:5;5172:32;5162:60;;5218:1;5215;5208:12;5233:382;5298:6;5306;5359:2;5347:9;5338:7;5334:23;5330:32;5327:52;;;5375:1;5372;5365:12;5327:52;5414:9;5401:23;5433:31;5458:5;5433:31;:::i;:::-;5483:5;-1:-1:-1;5540:2:1;5525:18;;5512:32;5553:30;5512:32;5553:30;:::i;:::-;5602:7;5592:17;;;5233:382;;;;;:::o;5620:1151::-;5892:2;5904:21;;;5974:13;;5877:18;;;5996:22;;;5844:4;;6075:15;;;6049:2;6034:18;;;5844:4;6118:627;6132:6;6129:1;6126:13;6118:627;;;6197:6;6191:13;6235:2;6229:9;6224:3;6217:22;6297:34;6291:2;6287;6283:11;6277:18;6273:59;6268:2;6263:3;6259:12;6252:81;6396:2;6392;6388:11;6382:18;6378:2;6367:34;6362:2;6357:3;6353:12;6346:56;6464:34;6456:4;6452:2;6448:13;6442:20;6438:61;6431:4;6426:3;6422:14;6415:85;6562:42;6554:4;6550:2;6546:13;6540:20;6536:69;6529:4;6524:3;6520:14;6513:93;6656:4;6652:2;6648:13;6642:20;6635:4;6630:3;6626:14;6619:44;;6692:4;6687:3;6683:14;6676:21;;6732:2;6724:6;6720:15;6710:25;;6154:1;6151;6147:9;6142:14;;6118:627;;6776:367;6844:6;6852;6905:2;6893:9;6884:7;6880:23;6876:32;6873:52;;;6921:1;6918;6911:12;6873:52;6960:9;6947:23;6979:31;7004:5;6979:31;:::i;:::-;7029:5;7107:2;7092:18;;;;7079:32;;-1:-1:-1;;;6776:367:1:o;8090:184::-;8142:77;8139:1;8132:88;8239:4;8236:1;8229:15;8263:4;8260:1;8253:15;10806:230;10876:6;10929:2;10917:9;10908:7;10904:23;10900:32;10897:52;;;10945:1;10942;10935:12;10897:52;-1:-1:-1;10990:16:1;;10806:230;-1:-1:-1;10806:230:1:o;11041:192::-;11120:13;;11173:34;11162:46;;11152:57;;11142:85;;11223:1;11220;11213:12;11142:85;11041:192;;;:::o;11238:208::-;11308:6;11361:2;11349:9;11340:7;11336:23;11332:32;11329:52;;;11377:1;11374;11367:12;11329:52;11400:40;11430:9;11400:40;:::i;11451:138::-;11530:13;;11552:31;11530:13;11552:31;:::i;11594:251::-;11664:6;11717:2;11705:9;11696:7;11692:23;11688:32;11685:52;;;11733:1;11730;11723:12;11685:52;11765:9;11759:16;11784:31;11809:5;11784:31;:::i;11850:166::-;11928:13;;11981:2;11970:21;;;11960:32;;11950:60;;12006:1;12003;11996:12;12021:1527;12107:5;12160:3;12153:4;12145:6;12141:17;12137:27;12127:55;;12178:1;12175;12168:12;12127:55;12211:6;12205:13;12255:4;12247:6;12243:17;12284:1;12306;12330:18;12322:6;12319:30;12316:56;;;12352:18;;:::i;:::-;12409:4;12400:6;12397:1;12393:14;12389:25;12381:33;;12434:21;12450:4;12434:21;:::i;:::-;12491:23;;;12589:1;12585:14;;;;12571:29;;;12423:32;-1:-1:-1;;12543:4:1;12530:18;;12612:15;;;12609:35;;;12640:1;12637;12630:12;12609:35;12697:6;12692:3;12689:15;12681:836;;;12766:1;12802:4;12796:3;12791;12787:13;12783:24;12780:44;;;12820:1;12817;12810:12;12780:44;12881:2;12875:9;12927:4;12915:17;;12966:18;12951:34;;12987:22;;;12948:62;12945:88;;;13013:18;;:::i;:::-;13053:2;13046:22;13149:10;;13172:23;;;13149:10;-1:-1:-1;13234:45:1;13273:4;13264:14;;13234:45;:::i;:::-;13227:4;13219:6;13215:17;13208:72;13317:42;13355:2;13350:3;13346:12;13317:42;:::i;:::-;13312:2;13304:6;13300:15;13293:67;13397:43;13436:2;13431:3;13427:12;13397:43;:::i;:::-;13392:2;13380:15;;13373:68;13454:19;;-1:-1:-1;12723:4:1;12714:14;;;;;13502:4;13493:14;12681:836;;;-1:-1:-1;13535:7:1;12021:1527;-1:-1:-1;;;;;12021:1527:1:o;13553:588::-;13613:5;13666:3;13659:4;13651:6;13647:17;13643:27;13633:55;;13684:1;13681;13674:12;13633:55;13785:19;13763:2;13785:19;:::i;:::-;13828:3;13866:2;13858:6;13854:15;13892:3;13884:6;13881:15;13878:35;;;13909:1;13906;13899:12;13878:35;13933:6;13948:162;13964:6;13959:3;13956:15;13948:162;;;14032:33;14061:3;14032:33;:::i;:::-;14020:46;;14095:4;14086:14;;;;13981;13948:162;;14146:1380;14254:6;14307:2;14295:9;14286:7;14282:23;14278:32;14275:52;;;14323:1;14320;14313:12;14275:52;14356:9;14350:16;14389:18;14381:6;14378:30;14375:50;;;14421:1;14418;14411:12;14375:50;14444:22;;14500:6;14482:16;;;14478:29;14475:49;;;14520:1;14517;14510:12;14475:49;14546:22;;:::i;:::-;14591:33;14621:2;14591:33;:::i;:::-;14577:48;;14684:2;14676:11;;;14670:18;14704:14;;;14697:31;14767:2;14759:11;;14753:18;14796;14783:32;;14780:52;;;14828:1;14825;14818:12;14780:52;14864:88;14944:7;14933:8;14929:2;14925:17;14864:88;:::i;:::-;14859:2;14852:5;14848:14;14841:112;;14992:2;14988;14984:11;14978:18;15021;15011:8;15008:32;15005:52;;;15053:1;15050;15043:12;15005:52;15089:88;15169:7;15158:8;15154:2;15150:17;15089:88;:::i;:::-;15084:2;15077:5;15073:14;15066:112;;15217:3;15213:2;15209:12;15203:19;15247:18;15237:8;15234:32;15231:52;;;15279:1;15276;15269:12;15231:52;15316:88;15396:7;15385:8;15381:2;15377:17;15316:88;:::i;:::-;15310:3;15303:5;15299:15;15292:113;;15438:57;15487:7;15481:3;15477:2;15473:12;15438:57;:::i;:::-;15432:3;15421:15;;15414:82;15425:5;14146:1380;-1:-1:-1;;;;14146:1380:1:o;16230:184::-;16282:77;16279:1;16272:88;16379:4;16376:1;16369:15;16403:4;16400:1;16393:15;16419:125;16484:9;;;16505:10;;;16502:36;;;16518:18;;:::i;:::-;16419:125;;;;:::o;16900:243::-;17022:34;17015:42;;;16971;;;16967:91;;17070:44;;17067:70;;;17117:18;;:::i;17456:195::-;17495:3;17526:66;17519:5;17516:77;17513:103;;17596:18;;:::i;:::-;-1:-1:-1;17643:1:1;17632:13;;17456:195::o;19041:175::-;19119:13;;19172:18;19161:30;;19151:41;;19141:69;;19206:1;19203;19196:12;19221:693;19322:6;19382:2;19370:9;19361:7;19357:23;19353:32;19397:2;19394:22;;;19412:1;19409;19402:12;19394:22;-1:-1:-1;19481:2:1;19475:9;19523:2;19511:15;;19556:18;19541:34;;19577:22;;;19538:62;19535:88;;;19603:18;;:::i;:::-;19639:2;19632:22;19678:40;19708:9;19678:40;:::i;:::-;19670:6;19663:56;19752:48;19796:2;19785:9;19781:18;19752:48;:::i;:::-;19747:2;19739:6;19735:15;19728:73;19834:48;19878:2;19867:9;19863:18;19834:48;:::i;:::-;19829:2;19817:15;;19810:73;19821:6;19221:693;-1:-1:-1;;;19221:693:1:o;20569:301::-;20698:3;20736:6;20730:13;20782:6;20775:4;20767:6;20763:17;20758:3;20752:37;20844:1;20808:16;;20833:13;;;-1:-1:-1;20808:16:1;20569:301;-1:-1:-1;20569:301:1:o;20875:245::-;20942:6;20995:2;20983:9;20974:7;20970:23;20966:32;20963:52;;;21011:1;21008;21001:12;20963:52;21043:9;21037:16;21062:28;21084:5;21062:28;:::i
Swarm Source
ipfs://906e77c6f61b3057feae5009f729232e2975ab0fb6ae39d9a4d084df7d210dc1
Loading...
Loading
Loading...
Loading
Loading...
Loading
Net Worth in USD
$2,639.10
Net Worth in FRAX
2,556.541238
Token Allocations
FXS
98.70%
CVX
0.85%
CRV
0.44%
Multichain Portfolio | 35 Chains
Loading...
Loading
Loading...
Loading
Loading...
Loading
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.