Source Code
Overview
ETH Balance
0 ETH
Token Holdings
More Info
ContractCreator
Multi Chain
Multichain Addresses
N/ALatest 25 from a total of 62 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
Value | ||||
---|---|---|---|---|---|---|---|---|---|
Simple Wrap Tran... | 8176550 | 352 days 49 mins ago | IN | 0 ETH | 0.00128474 | ||||
Repay Max And Un... | 8170084 | 353 days 3 hrs ago | IN | 0 ETH | 0.00055989 | ||||
Simple Wrap Tran... | 8165184 | 353 days 23 hrs ago | IN | 0 ETH | 0.00079086 | ||||
Repay Max And Un... | 8164554 | 354 days 2 hrs ago | IN | 0 ETH | 0.00054933 | ||||
Repay Max And Un... | 8164333 | 354 days 3 hrs ago | IN | 0 ETH | 0.00063672 | ||||
Repay Max And Un... | 8164114 | 354 days 3 hrs ago | IN | 0 ETH | 0.00054789 | ||||
Repay Max And Un... | 8164100 | 354 days 4 hrs ago | IN | 0 ETH | 0.00054959 | ||||
Repay Max And Un... | 8164036 | 354 days 4 hrs ago | IN | 0 ETH | 0.00063337 | ||||
Simple Wrap Tran... | 8164002 | 354 days 4 hrs ago | IN | 0 ETH | 0.00067135 | ||||
Simple Withdraw ... | 8163972 | 354 days 4 hrs ago | IN | 0 ETH | 0.000394 | ||||
Simple Wrap Tran... | 8163967 | 354 days 4 hrs ago | IN | 0 ETH | 0.00067438 | ||||
Simple Withdraw ... | 8140032 | 358 days 5 hrs ago | IN | 0 ETH | 0.00803371 | ||||
Simple Wrap Tran... | 8140027 | 358 days 5 hrs ago | IN | 0 ETH | 0.01516563 | ||||
Simple Withdraw ... | 8140001 | 358 days 5 hrs ago | IN | 0 ETH | 0.01021313 | ||||
Simple Withdraw ... | 8139954 | 358 days 6 hrs ago | IN | 0 ETH | 0.01580727 | ||||
Simple Withdraw ... | 8139846 | 358 days 6 hrs ago | IN | 0 ETH | 0.01621372 | ||||
Simple Wrap Tran... | 8130304 | 359 days 20 hrs ago | IN | 0 ETH | 0.00076533 | ||||
Simple Wrap Tran... | 8041267 | 374 days 11 hrs ago | IN | 0 ETH | 0.00138492 | ||||
Simple Wrap Tran... | 7922361 | 394 days 5 hrs ago | IN | 0 ETH | 0.00092023 | ||||
Simple Wrap Tran... | 7917650 | 394 days 23 hrs ago | IN | 0 ETH | 0.00366929 | ||||
Simple Wrap Tran... | 7911030 | 396 days 1 hr ago | IN | 0 ETH | 0.01218998 | ||||
Simple Wrap Tran... | 7910745 | 396 days 2 hrs ago | IN | 0 ETH | 0.02758257 | ||||
Simple Wrap Tran... | 7910601 | 396 days 2 hrs ago | IN | 0 ETH | 0.02705153 | ||||
Simple Wrap Tran... | 7910527 | 396 days 2 hrs ago | IN | 0 ETH | 0.02710042 | ||||
Simple Wrap Tran... | 7878950 | 401 days 4 hrs ago | IN | 0 ETH | 0.02808792 |
Latest 25 internal transactions (View All)
Advanced mode:
Parent Txn Hash | Block | From | To | Value | ||
---|---|---|---|---|---|---|
8176550 | 352 days 49 mins ago | 0 ETH | ||||
8176550 | 352 days 49 mins ago | 0 ETH | ||||
8176550 | 352 days 49 mins ago | 0 ETH | ||||
8176550 | 352 days 49 mins ago | 0 ETH | ||||
8176550 | 352 days 49 mins ago | 0 ETH | ||||
8176550 | 352 days 49 mins ago | 0 ETH | ||||
8176550 | 352 days 49 mins ago | 0 ETH | ||||
8176550 | 352 days 49 mins ago | 0 ETH | ||||
8176550 | 352 days 49 mins ago | 0 ETH | ||||
8176550 | 352 days 49 mins ago | 0 ETH | ||||
8176550 | 352 days 49 mins ago | 0 ETH | ||||
8176550 | 352 days 49 mins ago | 0 ETH | ||||
8176550 | 352 days 49 mins ago | 0 ETH | ||||
8176550 | 352 days 49 mins ago | 0 ETH | ||||
8176550 | 352 days 49 mins ago | 0 ETH | ||||
8176550 | 352 days 49 mins ago | 0 ETH | ||||
8176550 | 352 days 49 mins ago | 0 ETH | ||||
8176550 | 352 days 49 mins ago | 0 ETH | ||||
8176550 | 352 days 49 mins ago | 0 ETH | ||||
8176550 | 352 days 49 mins ago | 0 ETH | ||||
8176550 | 352 days 49 mins ago | 0 ETH | ||||
8176550 | 352 days 49 mins ago | 0 ETH | ||||
8176550 | 352 days 49 mins ago | 0 ETH | ||||
8176550 | 352 days 49 mins ago | 0 ETH | ||||
8176550 | 352 days 49 mins ago | 0 ETH |
Loading...
Loading
Contract Name:
StagingLoanRouter
Compiler Version
v0.8.13+commit.abaa5c0e
Optimization Enabled:
Yes with 200 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: UNLICENSED pragma solidity 0.8.13; import "../interfaces/IStagingLoanRouter.sol"; import "../interfaces/IConvertibleBondBox.sol"; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import "@openzeppelin/contracts/utils/Context.sol"; import "@uniswap/lib/contracts/libraries/TransferHelper.sol"; import "@buttonwood-protocol/tranche/contracts/interfaces/IBondController.sol"; import "@buttonwood-protocol/tranche/contracts/interfaces/ITranche.sol"; import "@buttonwood-protocol/button-wrappers/contracts/interfaces/IButtonToken.sol"; import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; import "@openzeppelin/contracts/utils/math/Math.sol"; import "forge-std/console2.sol"; contract StagingLoanRouter is IStagingLoanRouter, Context { /** * @inheritdoc IStagingLoanRouter */ function simpleWrapTrancheBorrow( IStagingBox _stagingBox, uint256 _amountRaw, uint256 _minBorrowSlips ) public { ( IConvertibleBondBox convertibleBondBox, IBondController bond, IButtonToken wrapper, IERC20 underlying ) = fetchElasticStack(_stagingBox); TransferHelper.safeTransferFrom( address(underlying), _msgSender(), address(this), _amountRaw ); if ( underlying.allowance(address(this), address(wrapper)) < _amountRaw ) { underlying.approve(address(wrapper), type(uint256).max); } uint256 wrapperAmount = wrapper.deposit(_amountRaw); wrapper.approve(address(bond), type(uint256).max); bond.deposit(wrapperAmount); uint256 riskTrancheBalance = _stagingBox.riskTranche().balanceOf( address(this) ); uint256 safeTrancheBalance = _stagingBox.safeTranche().balanceOf( address(this) ); if ( _stagingBox.safeTranche().allowance( address(this), address(_stagingBox) ) < safeTrancheBalance ) { _stagingBox.safeTranche().approve( address(_stagingBox), type(uint256).max ); } if ( _stagingBox.riskTranche().allowance( address(this), address(_stagingBox) ) < riskTrancheBalance ) { _stagingBox.riskTranche().approve( address(_stagingBox), type(uint256).max ); } uint256 borrowAmount = (Math.min( safeTrancheBalance, ((riskTrancheBalance * convertibleBondBox.safeRatio()) / convertibleBondBox.riskRatio()) ) * _stagingBox.initialPrice() * _stagingBox.stableDecimals()) / _stagingBox.priceGranularity() / _stagingBox.trancheDecimals(); _stagingBox.depositBorrow(_msgSender(), borrowAmount); if (borrowAmount < _minBorrowSlips) revert SlippageExceeded({ expectedAmount: borrowAmount, minAmount: _minBorrowSlips }); } /** * @inheritdoc IStagingLoanRouter */ function multiWrapTrancheBorrow( IStagingBox _stagingBox, uint256 _amountRaw, uint256 _minBorrowSlips ) external { simpleWrapTrancheBorrow(_stagingBox, _amountRaw, _minBorrowSlips); ( IConvertibleBondBox convertibleBondBox, IBondController bond, , ) = fetchElasticStack(_stagingBox); //send back unused tranches to _msgSender() uint256 trancheCount = bond.trancheCount(); uint256 trancheIndex = convertibleBondBox.trancheIndex(); for (uint256 i = 0; i < trancheCount; ) { if (i != trancheIndex && i != trancheCount - 1) { (ITranche tranche, ) = bond.tranches(i); tranche.transfer( _msgSender(), tranche.balanceOf(address(this)) ); } unchecked { ++i; } } } /** * @inheritdoc IStagingLoanRouter */ function simpleWithdrawBorrowUnwrap( IStagingBox _stagingBox, uint256 _borrowSlipAmount ) external { //transfer borrowSlips _stagingBox.borrowSlip().transferFrom( _msgSender(), address(this), _borrowSlipAmount ); //approve borrowSlips for StagingBox if ( _stagingBox.borrowSlip().allowance( address(this), address(_stagingBox) ) < _borrowSlipAmount ) { _stagingBox.borrowSlip().approve( address(_stagingBox), type(uint256).max ); } //withdraw borrowSlips for tranches _stagingBox.withdrawBorrow(_borrowSlipAmount); //redeem tranches with underlying bond & mature _redeemTrancheImmatureUnwrap(_stagingBox); } /** * @inheritdoc IStagingLoanRouter */ function redeemLendSlipsForStables( IStagingBox _stagingBox, uint256 _lendSlipAmount ) external { (IConvertibleBondBox convertibleBondBox, , , ) = fetchElasticStack( _stagingBox ); _stagingBox.lendSlip().transferFrom( _msgSender(), address(this), _lendSlipAmount ); //redeem lendSlips for SafeSlips _stagingBox.redeemLendSlip(_lendSlipAmount); //get balance of SafeSlips and redeem for stables uint256 safeSlipAmount = IERC20(_stagingBox.safeSlipAddress()) .balanceOf(address(this)); convertibleBondBox.redeemStable(safeSlipAmount); //get balance of stables and send back to user uint256 stableBalance = convertibleBondBox.stableToken().balanceOf( address(this) ); TransferHelper.safeTransfer( address(convertibleBondBox.stableToken()), _msgSender(), stableBalance ); } /** * @inheritdoc IStagingLoanRouter */ function redeemLendSlipsForTranchesAndUnwrap( IStagingBox _stagingBox, uint256 _lendSlipAmount ) external { //Transfer lendslips to router _stagingBox.lendSlip().transferFrom( _msgSender(), address(this), _lendSlipAmount ); //redeem lendSlips for SafeSlips _stagingBox.redeemLendSlip(_lendSlipAmount); //redeem SafeSlips for SafeTranche uint256 safeSlipAmount = IERC20(_stagingBox.safeSlipAddress()) .balanceOf(address(this)); _safeSlipsForTranchesUnwrap(_stagingBox, safeSlipAmount); } /** * @inheritdoc IStagingLoanRouter */ function redeemSafeSlipsForTranchesAndUnwrap( IStagingBox _stagingBox, uint256 _safeSlipAmount ) external { (IConvertibleBondBox convertibleBondBox, , , ) = fetchElasticStack( _stagingBox ); //Transfer safeslips to router convertibleBondBox.safeSlip().transferFrom( _msgSender(), address(this), _safeSlipAmount ); _safeSlipsForTranchesUnwrap(_stagingBox, _safeSlipAmount); } function _safeSlipsForTranchesUnwrap( IStagingBox _stagingBox, uint256 _safeSlipAmount ) internal { ( IConvertibleBondBox convertibleBondBox, IBondController bond, IButtonToken wrapper, ) = fetchElasticStack(_stagingBox); convertibleBondBox.redeemSafeTranche(_safeSlipAmount); //redeem SafeTranche for underlying collateral uint256 safeTrancheAmount = convertibleBondBox.safeTranche().balanceOf( address(this) ); bond.redeemMature( address(convertibleBondBox.safeTranche()), safeTrancheAmount ); //redeem penalty riskTranche uint256 riskTrancheAmount = convertibleBondBox.riskTranche().balanceOf( address(this) ); if (riskTrancheAmount > 0) { bond.redeemMature( address(convertibleBondBox.riskTranche()), riskTrancheAmount ); } //unwrap to _msgSender() wrapper.withdrawAllTo(_msgSender()); } /** * @inheritdoc IStagingLoanRouter */ function redeemRiskSlipsForTranchesAndUnwrap( IStagingBox _stagingBox, uint256 _riskSlipAmount ) external { ( IConvertibleBondBox convertibleBondBox, IBondController bond, IButtonToken wrapper, ) = fetchElasticStack(_stagingBox); //Transfer riskSlips to router convertibleBondBox.riskSlip().transferFrom( _msgSender(), address(this), _riskSlipAmount ); //Redeem riskSlips for riskTranches convertibleBondBox.redeemRiskTranche(_riskSlipAmount); //redeem riskTranche for underlying collateral uint256 riskTrancheAmount = convertibleBondBox.riskTranche().balanceOf( address(this) ); bond.redeemMature( address(convertibleBondBox.riskTranche()), riskTrancheAmount ); //unwrap to _msgSender() wrapper.withdrawAllTo(_msgSender()); } /** * @inheritdoc IStagingLoanRouter */ function repayAndUnwrapSimple( IStagingBox _stagingBox, uint256 _stableAmount, uint256 _stableFees, uint256 _riskSlipAmount ) external { (IConvertibleBondBox convertibleBondBox, , , ) = fetchElasticStack( _stagingBox ); //Transfer Stables to Router TransferHelper.safeTransferFrom( address(convertibleBondBox.stableToken()), _msgSender(), address(this), _stableAmount + _stableFees ); //Calculate RiskSlips (minus fees) and transfer to router convertibleBondBox.riskSlip().transferFrom( _msgSender(), address(this), _riskSlipAmount ); //call repay function if ( convertibleBondBox.stableToken().allowance( address(this), address(convertibleBondBox) ) < _stableAmount + _stableFees ) { SafeERC20.safeIncreaseAllowance( (convertibleBondBox.stableToken()), address(convertibleBondBox), type(uint256).max - _stableAmount - _stableFees ); } convertibleBondBox.repay(_stableAmount); _redeemTrancheImmatureUnwrap(_stagingBox); //send unpaid riskSlip back convertibleBondBox.riskSlip().transfer( _msgSender(), IERC20(_stagingBox.riskSlipAddress()).balanceOf(address(this)) ); } /** * @inheritdoc IStagingLoanRouter */ function repayMaxAndUnwrapSimple( IStagingBox _stagingBox, uint256 _stableAmount, uint256 _stableFees, uint256 _riskSlipAmount ) external { (IConvertibleBondBox convertibleBondBox, , , ) = fetchElasticStack( _stagingBox ); //Transfer Stables + fees + slippage to Router TransferHelper.safeTransferFrom( address(convertibleBondBox.stableToken()), _msgSender(), address(this), _stableAmount + _stableFees ); //Transfer risk slips to CBB convertibleBondBox.riskSlip().transferFrom( _msgSender(), address(this), _riskSlipAmount ); //call repayMax function if ( convertibleBondBox.stableToken().allowance( address(this), address(convertibleBondBox) ) < _stableAmount + _stableFees ) { SafeERC20.safeIncreaseAllowance( (convertibleBondBox.stableToken()), address(convertibleBondBox), type(uint256).max - _stableAmount - _stableFees ); } convertibleBondBox.repayMax(_riskSlipAmount); _redeemTrancheImmatureUnwrap(_stagingBox); //send unused stables back to _msgSender() TransferHelper.safeTransfer( address(convertibleBondBox.stableToken()), _msgSender(), convertibleBondBox.stableToken().balanceOf(address(this)) ); } function _redeemTrancheImmatureUnwrap(IStagingBox _stagingBox) internal { ( IConvertibleBondBox convertibleBondBox, IBondController bond, IButtonToken wrapper, ) = fetchElasticStack(_stagingBox); uint256 safeRatio = convertibleBondBox.safeRatio(); uint256 riskRatio = convertibleBondBox.riskRatio(); uint256[] memory redeemAmounts = new uint256[](2); redeemAmounts[0] = convertibleBondBox.safeTranche().balanceOf( address(this) ); redeemAmounts[1] = convertibleBondBox.riskTranche().balanceOf( address(this) ); if (redeemAmounts[0] * riskRatio < redeemAmounts[1] * safeRatio) { redeemAmounts[1] = (redeemAmounts[0] * riskRatio) / safeRatio; } else { redeemAmounts[0] = (redeemAmounts[1] * safeRatio) / riskRatio; } redeemAmounts[0] -= redeemAmounts[0] % safeRatio; redeemAmounts[1] -= redeemAmounts[1] % riskRatio; bond.redeem(redeemAmounts); //unwrap rebasing collateral and send underlying to _msgSender() wrapper.withdrawAllTo(_msgSender()); } /** * @inheritdoc IStagingLoanRouter */ function repayAndUnwrapMature( IStagingBox _stagingBox, uint256 _stableAmount, uint256 _stableFees, uint256 _riskSlipAmount ) external { ( IConvertibleBondBox convertibleBondBox, IBondController bond, IButtonToken wrapper, ) = fetchElasticStack(_stagingBox); //Transfer Stables to Router TransferHelper.safeTransferFrom( address(convertibleBondBox.stableToken()), _msgSender(), address(this), _stableAmount + _stableFees ); //Transfer to router convertibleBondBox.riskSlip().transferFrom( _msgSender(), address(this), _riskSlipAmount ); //call repay function if ( convertibleBondBox.stableToken().allowance( address(this), address(convertibleBondBox) ) < _stableAmount + _stableFees ) { SafeERC20.safeIncreaseAllowance( (convertibleBondBox.stableToken()), address(convertibleBondBox), type(uint256).max - _stableAmount - _stableFees ); } convertibleBondBox.repay(_stableAmount); //call redeemMature on bond bond.redeemMature( address(convertibleBondBox.safeTranche()), convertibleBondBox.safeTranche().balanceOf(address(this)) ); bond.redeemMature( address(convertibleBondBox.riskTranche()), convertibleBondBox.riskTranche().balanceOf(address(this)) ); //unwrap rebasing collateral to _msgSender() wrapper.withdrawAllTo(_msgSender()); } function fetchElasticStack(IStagingBox _stagingBox) internal view returns ( IConvertibleBondBox, IBondController, IButtonToken, IERC20 ) { IConvertibleBondBox convertibleBondBox = _stagingBox .convertibleBondBox(); IBondController bond = convertibleBondBox.bond(); IButtonToken wrapper = IButtonToken(bond.collateralToken()); IERC20 underlying = IERC20(wrapper.underlying()); return (convertibleBondBox, bond, wrapper, underlying); } }
// SPDX-License-Identifier: GPL-3.0-or-later import "./IRebasingERC20.sol"; import "./IButtonWrapper.sol"; // Interface definition for the ButtonToken ERC20 wrapper contract interface IButtonToken is IButtonWrapper, IRebasingERC20 { /// @dev The reference to the oracle which feeds in the /// price of the underlying token. function oracle() external view returns (address); /// @dev Most recent price recorded from the oracle. function lastPrice() external view returns (uint256); /// @dev Update reference to the oracle contract and resets price. /// @param oracle_ The address of the new oracle. function updateOracle(address oracle_) external; /// @dev Log to record changes to the oracle. /// @param oracle The address of the new oracle. event OracleUpdated(address oracle); /// @dev Contract initializer function initialize( address underlying_, string memory name_, string memory symbol_, address oracle_ ) external; }
// SPDX-License-Identifier: GPL-3.0-or-later // Interface definition for ButtonWrapper contract, which wraps an // underlying ERC20 token into a new ERC20 with different characteristics. // NOTE: "uAmount" => underlying token (wrapped) amount and // "amount" => wrapper token amount interface IButtonWrapper { //-------------------------------------------------------------------------- // ButtonWrapper write methods /// @notice Transfers underlying tokens from {msg.sender} to the contract and /// mints wrapper tokens. /// @param amount The amount of wrapper tokens to mint. /// @return The amount of underlying tokens deposited. function mint(uint256 amount) external returns (uint256); /// @notice Transfers underlying tokens from {msg.sender} to the contract and /// mints wrapper tokens to the specified beneficiary. /// @param to The beneficiary account. /// @param amount The amount of wrapper tokens to mint. /// @return The amount of underlying tokens deposited. function mintFor(address to, uint256 amount) external returns (uint256); /// @notice Burns wrapper tokens from {msg.sender} and transfers /// the underlying tokens back. /// @param amount The amount of wrapper tokens to burn. /// @return The amount of underlying tokens withdrawn. function burn(uint256 amount) external returns (uint256); /// @notice Burns wrapper tokens from {msg.sender} and transfers /// the underlying tokens to the specified beneficiary. /// @param to The beneficiary account. /// @param amount The amount of wrapper tokens to burn. /// @return The amount of underlying tokens withdrawn. function burnTo(address to, uint256 amount) external returns (uint256); /// @notice Burns all wrapper tokens from {msg.sender} and transfers /// the underlying tokens back. /// @return The amount of underlying tokens withdrawn. function burnAll() external returns (uint256); /// @notice Burns all wrapper tokens from {msg.sender} and transfers /// the underlying tokens back. /// @param to The beneficiary account. /// @return The amount of underlying tokens withdrawn. function burnAllTo(address to) external returns (uint256); /// @notice Transfers underlying tokens from {msg.sender} to the contract and /// mints wrapper tokens to the specified beneficiary. /// @param uAmount The amount of underlying tokens to deposit. /// @return The amount of wrapper tokens mint. function deposit(uint256 uAmount) external returns (uint256); /// @notice Transfers underlying tokens from {msg.sender} to the contract and /// mints wrapper tokens to the specified beneficiary. /// @param to The beneficiary account. /// @param uAmount The amount of underlying tokens to deposit. /// @return The amount of wrapper tokens mint. function depositFor(address to, uint256 uAmount) external returns (uint256); /// @notice Burns wrapper tokens from {msg.sender} and transfers /// the underlying tokens back. /// @param uAmount The amount of underlying tokens to withdraw. /// @return The amount of wrapper tokens burnt. function withdraw(uint256 uAmount) external returns (uint256); /// @notice Burns wrapper tokens from {msg.sender} and transfers /// the underlying tokens back to the specified beneficiary. /// @param to The beneficiary account. /// @param uAmount The amount of underlying tokens to withdraw. /// @return The amount of wrapper tokens burnt. function withdrawTo(address to, uint256 uAmount) external returns (uint256); /// @notice Burns all wrapper tokens from {msg.sender} and transfers /// the underlying tokens back. /// @return The amount of wrapper tokens burnt. function withdrawAll() external returns (uint256); /// @notice Burns all wrapper tokens from {msg.sender} and transfers /// the underlying tokens back. /// @param to The beneficiary account. /// @return The amount of wrapper tokens burnt. function withdrawAllTo(address to) external returns (uint256); //-------------------------------------------------------------------------- // ButtonWrapper view methods /// @return The address of the underlying token. function underlying() external view returns (address); /// @return The total underlying tokens held by the wrapper contract. function totalUnderlying() external view returns (uint256); /// @param who The account address. /// @return The underlying token balance of the account. function balanceOfUnderlying(address who) external view returns (uint256); /// @param uAmount The amount of underlying tokens. /// @return The amount of wrapper tokens exchangeable. function underlyingToWrapper(uint256 uAmount) external view returns (uint256); /// @param amount The amount of wrapper tokens. /// @return The amount of underlying tokens exchangeable. function wrapperToUnderlying(uint256 amount) external view returns (uint256); }
// SPDX-License-Identifier: GPL-3.0-or-later import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol"; // Interface definition for Rebasing ERC20 tokens which have a "elastic" external // balance and "fixed" internal balance. Each user's external balance is // represented as a product of a "scalar" and the user's internal balance. // // From time to time the "Rebase" event updates scaler, // which increases/decreases all user balances proportionally. // // The standard ERC-20 methods are denominated in the elastic balance // interface IRebasingERC20 is IERC20, IERC20Metadata { /// @notice Returns the fixed balance of the specified address. /// @param who The address to query. function scaledBalanceOf(address who) external view returns (uint256); /// @notice Returns the total fixed supply. function scaledTotalSupply() external view returns (uint256); /// @notice Transfer all of the sender's balance to a specified address. /// @param to The address to transfer to. /// @return True on success, false otherwise. function transferAll(address to) external returns (bool); /// @notice Transfer all balance tokens from one address to another. /// @param from The address to send tokens from. /// @param to The address to transfer to. function transferAllFrom(address from, address to) external returns (bool); /// @notice Triggers the next rebase, if applicable. function rebase() external; /// @notice Event emitted when the balance scalar is updated. /// @param epoch The number of rebases since inception. /// @param newScalar The new scalar. event Rebase(uint256 indexed epoch, uint256 newScalar); }
// SPDX-License-Identifier: MIT pragma solidity >=0.4.22 <0.9.0; // The orignal 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 _sendLogPayload(bytes memory payload) private view { uint256 payloadLength = payload.length; address consoleAddress = CONSOLE_ADDRESS; assembly { let payloadStart := add(payload, 32) let r := staticcall(gas(), consoleAddress, payloadStart, payloadLength, 0, 0) } } function log() internal view { _sendLogPayload(abi.encodeWithSignature("log()")); } function logInt(int256 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(int256)", p0)); } function logUint(uint256 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256)", p0)); } function logString(string memory p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(string)", p0)); } function logBool(bool p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool)", p0)); } function logAddress(address p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(address)", p0)); } function logBytes(bytes memory p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes)", p0)); } function logBytes1(bytes1 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes1)", p0)); } function logBytes2(bytes2 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes2)", p0)); } function logBytes3(bytes3 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes3)", p0)); } function logBytes4(bytes4 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes4)", p0)); } function logBytes5(bytes5 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes5)", p0)); } function logBytes6(bytes6 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes6)", p0)); } function logBytes7(bytes7 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes7)", p0)); } function logBytes8(bytes8 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes8)", p0)); } function logBytes9(bytes9 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes9)", p0)); } function logBytes10(bytes10 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes10)", p0)); } function logBytes11(bytes11 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes11)", p0)); } function logBytes12(bytes12 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes12)", p0)); } function logBytes13(bytes13 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes13)", p0)); } function logBytes14(bytes14 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes14)", p0)); } function logBytes15(bytes15 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes15)", p0)); } function logBytes16(bytes16 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes16)", p0)); } function logBytes17(bytes17 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes17)", p0)); } function logBytes18(bytes18 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes18)", p0)); } function logBytes19(bytes19 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes19)", p0)); } function logBytes20(bytes20 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes20)", p0)); } function logBytes21(bytes21 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes21)", p0)); } function logBytes22(bytes22 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes22)", p0)); } function logBytes23(bytes23 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes23)", p0)); } function logBytes24(bytes24 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes24)", p0)); } function logBytes25(bytes25 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes25)", p0)); } function logBytes26(bytes26 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes26)", p0)); } function logBytes27(bytes27 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes27)", p0)); } function logBytes28(bytes28 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes28)", p0)); } function logBytes29(bytes29 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes29)", p0)); } function logBytes30(bytes30 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes30)", p0)); } function logBytes31(bytes31 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes31)", p0)); } function logBytes32(bytes32 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes32)", p0)); } function log(uint256 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256)", p0)); } function log(string memory p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(string)", p0)); } function log(bool p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool)", p0)); } function log(address p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(address)", p0)); } function log(uint256 p0, uint256 p1) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256)", p0, p1)); } function log(uint256 p0, string memory p1) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,string)", p0, p1)); } function log(uint256 p0, bool p1) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,bool)", p0, p1)); } function log(uint256 p0, address p1) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,address)", p0, p1)); } function log(string memory p0, uint256 p1) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,uint256)", p0, p1)); } function log(string memory p0, string memory p1) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,string)", p0, p1)); } function log(string memory p0, bool p1) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,bool)", p0, p1)); } function log(string memory p0, address p1) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,address)", p0, p1)); } function log(bool p0, uint256 p1) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,uint256)", p0, p1)); } function log(bool p0, string memory p1) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,string)", p0, p1)); } function log(bool p0, bool p1) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,bool)", p0, p1)); } function log(bool p0, address p1) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,address)", p0, p1)); } function log(address p0, uint256 p1) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,uint256)", p0, p1)); } function log(address p0, string memory p1) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,string)", p0, p1)); } function log(address p0, bool p1) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,bool)", p0, p1)); } function log(address p0, address p1) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,address)", p0, p1)); } function log(uint256 p0, uint256 p1, uint256 p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,uint256)", p0, p1, p2)); } function log(uint256 p0, uint256 p1, string memory p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,string)", p0, p1, p2)); } function log(uint256 p0, uint256 p1, bool p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,bool)", p0, p1, p2)); } function log(uint256 p0, uint256 p1, address p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,address)", p0, p1, p2)); } function log(uint256 p0, string memory p1, uint256 p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,string,uint256)", p0, p1, p2)); } function log(uint256 p0, string memory p1, string memory p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,string,string)", p0, p1, p2)); } function log(uint256 p0, string memory p1, bool p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,string,bool)", p0, p1, p2)); } function log(uint256 p0, string memory p1, address p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,string,address)", p0, p1, p2)); } function log(uint256 p0, bool p1, uint256 p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,uint256)", p0, p1, p2)); } function log(uint256 p0, bool p1, string memory p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,string)", p0, p1, p2)); } function log(uint256 p0, bool p1, bool p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,bool)", p0, p1, p2)); } function log(uint256 p0, bool p1, address p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,address)", p0, p1, p2)); } function log(uint256 p0, address p1, uint256 p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,address,uint256)", p0, p1, p2)); } function log(uint256 p0, address p1, string memory p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,address,string)", p0, p1, p2)); } function log(uint256 p0, address p1, bool p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,address,bool)", p0, p1, p2)); } function log(uint256 p0, address p1, address p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,address,address)", p0, p1, p2)); } function log(string memory p0, uint256 p1, uint256 p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,uint256,uint256)", p0, p1, p2)); } function log(string memory p0, uint256 p1, string memory p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,uint256,string)", p0, p1, p2)); } function log(string memory p0, uint256 p1, bool p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,uint256,bool)", p0, p1, p2)); } function log(string memory p0, uint256 p1, address p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,uint256,address)", p0, p1, p2)); } function log(string memory p0, string memory p1, uint256 p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,string,uint256)", p0, p1, p2)); } function log(string memory p0, string memory p1, string memory p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,string,string)", p0, p1, p2)); } function log(string memory p0, string memory p1, bool p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,string,bool)", p0, p1, p2)); } function log(string memory p0, string memory p1, address p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,string,address)", p0, p1, p2)); } function log(string memory p0, bool p1, uint256 p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,bool,uint256)", p0, p1, p2)); } function log(string memory p0, bool p1, string memory p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,bool,string)", p0, p1, p2)); } function log(string memory p0, bool p1, bool p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,bool,bool)", p0, p1, p2)); } function log(string memory p0, bool p1, address p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,bool,address)", p0, p1, p2)); } function log(string memory p0, address p1, uint256 p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,address,uint256)", p0, p1, p2)); } function log(string memory p0, address p1, string memory p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,address,string)", p0, p1, p2)); } function log(string memory p0, address p1, bool p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,address,bool)", p0, p1, p2)); } function log(string memory p0, address p1, address p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,address,address)", p0, p1, p2)); } function log(bool p0, uint256 p1, uint256 p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,uint256)", p0, p1, p2)); } function log(bool p0, uint256 p1, string memory p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,string)", p0, p1, p2)); } function log(bool p0, uint256 p1, bool p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,bool)", p0, p1, p2)); } function log(bool p0, uint256 p1, address p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,address)", p0, p1, p2)); } function log(bool p0, string memory p1, uint256 p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,string,uint256)", p0, p1, p2)); } function log(bool p0, string memory p1, string memory p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,string,string)", p0, p1, p2)); } function log(bool p0, string memory p1, bool p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,string,bool)", p0, p1, p2)); } function log(bool p0, string memory p1, address p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,string,address)", p0, p1, p2)); } function log(bool p0, bool p1, uint256 p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint256)", p0, p1, p2)); } function log(bool p0, bool p1, string memory p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,bool,string)", p0, p1, p2)); } function log(bool p0, bool p1, bool p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool)", p0, p1, p2)); } function log(bool p0, bool p1, address p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,bool,address)", p0, p1, p2)); } function log(bool p0, address p1, uint256 p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,address,uint256)", p0, p1, p2)); } function log(bool p0, address p1, string memory p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,address,string)", p0, p1, p2)); } function log(bool p0, address p1, bool p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,address,bool)", p0, p1, p2)); } function log(bool p0, address p1, address p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,address,address)", p0, p1, p2)); } function log(address p0, uint256 p1, uint256 p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,uint256,uint256)", p0, p1, p2)); } function log(address p0, uint256 p1, string memory p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,uint256,string)", p0, p1, p2)); } function log(address p0, uint256 p1, bool p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,uint256,bool)", p0, p1, p2)); } function log(address p0, uint256 p1, address p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,uint256,address)", p0, p1, p2)); } function log(address p0, string memory p1, uint256 p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,string,uint256)", p0, p1, p2)); } function log(address p0, string memory p1, string memory p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,string,string)", p0, p1, p2)); } function log(address p0, string memory p1, bool p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,string,bool)", p0, p1, p2)); } function log(address p0, string memory p1, address p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,string,address)", p0, p1, p2)); } function log(address p0, bool p1, uint256 p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,bool,uint256)", p0, p1, p2)); } function log(address p0, bool p1, string memory p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,bool,string)", p0, p1, p2)); } function log(address p0, bool p1, bool p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,bool,bool)", p0, p1, p2)); } function log(address p0, bool p1, address p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,bool,address)", p0, p1, p2)); } function log(address p0, address p1, uint256 p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,address,uint256)", p0, p1, p2)); } function log(address p0, address p1, string memory p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,address,string)", p0, p1, p2)); } function log(address p0, address p1, bool p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,address,bool)", p0, p1, p2)); } function log(address p0, address p1, address p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,address,address)", p0, p1, p2)); } function log(uint256 p0, uint256 p1, uint256 p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,uint256,uint256)", p0, p1, p2, p3)); } function log(uint256 p0, uint256 p1, uint256 p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,uint256,string)", p0, p1, p2, p3)); } function log(uint256 p0, uint256 p1, uint256 p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,uint256,bool)", p0, p1, p2, p3)); } function log(uint256 p0, uint256 p1, uint256 p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,uint256,address)", p0, p1, p2, p3)); } function log(uint256 p0, uint256 p1, string memory p2, uint256 p3) internal view { _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 view { _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,string,string)", p0, p1, p2, p3)); } function log(uint256 p0, uint256 p1, string memory p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,string,bool)", p0, p1, p2, p3)); } function log(uint256 p0, uint256 p1, string memory p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,string,address)", p0, p1, p2, p3)); } function log(uint256 p0, uint256 p1, bool p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,bool,uint256)", p0, p1, p2, p3)); } function log(uint256 p0, uint256 p1, bool p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,bool,string)", p0, p1, p2, p3)); } function log(uint256 p0, uint256 p1, bool p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,bool,bool)", p0, p1, p2, p3)); } function log(uint256 p0, uint256 p1, bool p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,bool,address)", p0, p1, p2, p3)); } function log(uint256 p0, uint256 p1, address p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,address,uint256)", p0, p1, p2, p3)); } function log(uint256 p0, uint256 p1, address p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,address,string)", p0, p1, p2, p3)); } function log(uint256 p0, uint256 p1, address p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,address,bool)", p0, p1, p2, p3)); } function log(uint256 p0, uint256 p1, address p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,address,address)", p0, p1, p2, p3)); } function log(uint256 p0, string memory p1, uint256 p2, uint256 p3) internal view { _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 view { _sendLogPayload(abi.encodeWithSignature("log(uint256,string,uint256,string)", p0, p1, p2, p3)); } function log(uint256 p0, string memory p1, uint256 p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,string,uint256,bool)", p0, p1, p2, p3)); } function log(uint256 p0, string memory p1, uint256 p2, address p3) internal view { _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 view { _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 view { _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 view { _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 view { _sendLogPayload(abi.encodeWithSignature("log(uint256,string,string,address)", p0, p1, p2, p3)); } function log(uint256 p0, string memory p1, bool p2, uint256 p3) internal view { _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 view { _sendLogPayload(abi.encodeWithSignature("log(uint256,string,bool,string)", p0, p1, p2, p3)); } function log(uint256 p0, string memory p1, bool p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,string,bool,bool)", p0, p1, p2, p3)); } function log(uint256 p0, string memory p1, bool p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,string,bool,address)", p0, p1, p2, p3)); } function log(uint256 p0, string memory p1, address p2, uint256 p3) internal view { _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 view { _sendLogPayload(abi.encodeWithSignature("log(uint256,string,address,string)", p0, p1, p2, p3)); } function log(uint256 p0, string memory p1, address p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,string,address,bool)", p0, p1, p2, p3)); } function log(uint256 p0, string memory p1, address p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,string,address,address)", p0, p1, p2, p3)); } function log(uint256 p0, bool p1, uint256 p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,uint256,uint256)", p0, p1, p2, p3)); } function log(uint256 p0, bool p1, uint256 p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,uint256,string)", p0, p1, p2, p3)); } function log(uint256 p0, bool p1, uint256 p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,uint256,bool)", p0, p1, p2, p3)); } function log(uint256 p0, bool p1, uint256 p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,uint256,address)", p0, p1, p2, p3)); } function log(uint256 p0, bool p1, string memory p2, uint256 p3) internal view { _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 view { _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,string,string)", p0, p1, p2, p3)); } function log(uint256 p0, bool p1, string memory p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,string,bool)", p0, p1, p2, p3)); } function log(uint256 p0, bool p1, string memory p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,string,address)", p0, p1, p2, p3)); } function log(uint256 p0, bool p1, bool p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,bool,uint256)", p0, p1, p2, p3)); } function log(uint256 p0, bool p1, bool p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,bool,string)", p0, p1, p2, p3)); } function log(uint256 p0, bool p1, bool p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,bool,bool)", p0, p1, p2, p3)); } function log(uint256 p0, bool p1, bool p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,bool,address)", p0, p1, p2, p3)); } function log(uint256 p0, bool p1, address p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,address,uint256)", p0, p1, p2, p3)); } function log(uint256 p0, bool p1, address p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,address,string)", p0, p1, p2, p3)); } function log(uint256 p0, bool p1, address p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,address,bool)", p0, p1, p2, p3)); } function log(uint256 p0, bool p1, address p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,address,address)", p0, p1, p2, p3)); } function log(uint256 p0, address p1, uint256 p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,address,uint256,uint256)", p0, p1, p2, p3)); } function log(uint256 p0, address p1, uint256 p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,address,uint256,string)", p0, p1, p2, p3)); } function log(uint256 p0, address p1, uint256 p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,address,uint256,bool)", p0, p1, p2, p3)); } function log(uint256 p0, address p1, uint256 p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,address,uint256,address)", p0, p1, p2, p3)); } function log(uint256 p0, address p1, string memory p2, uint256 p3) internal view { _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 view { _sendLogPayload(abi.encodeWithSignature("log(uint256,address,string,string)", p0, p1, p2, p3)); } function log(uint256 p0, address p1, string memory p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,address,string,bool)", p0, p1, p2, p3)); } function log(uint256 p0, address p1, string memory p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,address,string,address)", p0, p1, p2, p3)); } function log(uint256 p0, address p1, bool p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,address,bool,uint256)", p0, p1, p2, p3)); } function log(uint256 p0, address p1, bool p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,address,bool,string)", p0, p1, p2, p3)); } function log(uint256 p0, address p1, bool p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,address,bool,bool)", p0, p1, p2, p3)); } function log(uint256 p0, address p1, bool p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,address,bool,address)", p0, p1, p2, p3)); } function log(uint256 p0, address p1, address p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,address,address,uint256)", p0, p1, p2, p3)); } function log(uint256 p0, address p1, address p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,address,address,string)", p0, p1, p2, p3)); } function log(uint256 p0, address p1, address p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,address,address,bool)", p0, p1, p2, p3)); } function log(uint256 p0, address p1, address p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,address,address,address)", p0, p1, p2, p3)); } function log(string memory p0, uint256 p1, uint256 p2, uint256 p3) internal view { _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 view { _sendLogPayload(abi.encodeWithSignature("log(string,uint256,uint256,string)", p0, p1, p2, p3)); } function log(string memory p0, uint256 p1, uint256 p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,uint256,uint256,bool)", p0, p1, p2, p3)); } function log(string memory p0, uint256 p1, uint256 p2, address p3) internal view { _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 view { _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 view { _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 view { _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 view { _sendLogPayload(abi.encodeWithSignature("log(string,uint256,string,address)", p0, p1, p2, p3)); } function log(string memory p0, uint256 p1, bool p2, uint256 p3) internal view { _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 view { _sendLogPayload(abi.encodeWithSignature("log(string,uint256,bool,string)", p0, p1, p2, p3)); } function log(string memory p0, uint256 p1, bool p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,uint256,bool,bool)", p0, p1, p2, p3)); } function log(string memory p0, uint256 p1, bool p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,uint256,bool,address)", p0, p1, p2, p3)); } function log(string memory p0, uint256 p1, address p2, uint256 p3) internal view { _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 view { _sendLogPayload(abi.encodeWithSignature("log(string,uint256,address,string)", p0, p1, p2, p3)); } function log(string memory p0, uint256 p1, address p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,uint256,address,bool)", p0, p1, p2, p3)); } function log(string memory p0, uint256 p1, address p2, address p3) internal view { _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 view { _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 view { _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 view { _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 view { _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 view { _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 view { _sendLogPayload(abi.encodeWithSignature("log(string,string,string,string)", p0, p1, p2, p3)); } function log(string memory p0, string memory p1, string memory p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,string,string,bool)", p0, p1, p2, p3)); } function log(string memory p0, string memory p1, string memory p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,string,string,address)", p0, p1, p2, p3)); } function log(string memory p0, string memory p1, bool p2, uint256 p3) internal view { _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 view { _sendLogPayload(abi.encodeWithSignature("log(string,string,bool,string)", p0, p1, p2, p3)); } function log(string memory p0, string memory p1, bool p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,string,bool,bool)", p0, p1, p2, p3)); } function log(string memory p0, string memory p1, bool p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,string,bool,address)", p0, p1, p2, p3)); } function log(string memory p0, string memory p1, address p2, uint256 p3) internal view { _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 view { _sendLogPayload(abi.encodeWithSignature("log(string,string,address,string)", p0, p1, p2, p3)); } function log(string memory p0, string memory p1, address p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,string,address,bool)", p0, p1, p2, p3)); } function log(string memory p0, string memory p1, address p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,string,address,address)", p0, p1, p2, p3)); } function log(string memory p0, bool p1, uint256 p2, uint256 p3) internal view { _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 view { _sendLogPayload(abi.encodeWithSignature("log(string,bool,uint256,string)", p0, p1, p2, p3)); } function log(string memory p0, bool p1, uint256 p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,bool,uint256,bool)", p0, p1, p2, p3)); } function log(string memory p0, bool p1, uint256 p2, address p3) internal view { _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 view { _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 view { _sendLogPayload(abi.encodeWithSignature("log(string,bool,string,string)", p0, p1, p2, p3)); } function log(string memory p0, bool p1, string memory p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,bool,string,bool)", p0, p1, p2, p3)); } function log(string memory p0, bool p1, string memory p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,bool,string,address)", p0, p1, p2, p3)); } function log(string memory p0, bool p1, bool p2, uint256 p3) internal view { _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 view { _sendLogPayload(abi.encodeWithSignature("log(string,bool,bool,string)", p0, p1, p2, p3)); } function log(string memory p0, bool p1, bool p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,bool,bool,bool)", p0, p1, p2, p3)); } function log(string memory p0, bool p1, bool p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,bool,bool,address)", p0, p1, p2, p3)); } function log(string memory p0, bool p1, address p2, uint256 p3) internal view { _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 view { _sendLogPayload(abi.encodeWithSignature("log(string,bool,address,string)", p0, p1, p2, p3)); } function log(string memory p0, bool p1, address p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,bool,address,bool)", p0, p1, p2, p3)); } function log(string memory p0, bool p1, address p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,bool,address,address)", p0, p1, p2, p3)); } function log(string memory p0, address p1, uint256 p2, uint256 p3) internal view { _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 view { _sendLogPayload(abi.encodeWithSignature("log(string,address,uint256,string)", p0, p1, p2, p3)); } function log(string memory p0, address p1, uint256 p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,address,uint256,bool)", p0, p1, p2, p3)); } function log(string memory p0, address p1, uint256 p2, address p3) internal view { _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 view { _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 view { _sendLogPayload(abi.encodeWithSignature("log(string,address,string,string)", p0, p1, p2, p3)); } function log(string memory p0, address p1, string memory p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,address,string,bool)", p0, p1, p2, p3)); } function log(string memory p0, address p1, string memory p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,address,string,address)", p0, p1, p2, p3)); } function log(string memory p0, address p1, bool p2, uint256 p3) internal view { _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 view { _sendLogPayload(abi.encodeWithSignature("log(string,address,bool,string)", p0, p1, p2, p3)); } function log(string memory p0, address p1, bool p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,address,bool,bool)", p0, p1, p2, p3)); } function log(string memory p0, address p1, bool p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,address,bool,address)", p0, p1, p2, p3)); } function log(string memory p0, address p1, address p2, uint256 p3) internal view { _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 view { _sendLogPayload(abi.encodeWithSignature("log(string,address,address,string)", p0, p1, p2, p3)); } function log(string memory p0, address p1, address p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,address,address,bool)", p0, p1, p2, p3)); } function log(string memory p0, address p1, address p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,address,address,address)", p0, p1, p2, p3)); } function log(bool p0, uint256 p1, uint256 p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,uint256,uint256)", p0, p1, p2, p3)); } function log(bool p0, uint256 p1, uint256 p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,uint256,string)", p0, p1, p2, p3)); } function log(bool p0, uint256 p1, uint256 p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,uint256,bool)", p0, p1, p2, p3)); } function log(bool p0, uint256 p1, uint256 p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,uint256,address)", p0, p1, p2, p3)); } function log(bool p0, uint256 p1, string memory p2, uint256 p3) internal view { _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 view { _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,string,string)", p0, p1, p2, p3)); } function log(bool p0, uint256 p1, string memory p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,string,bool)", p0, p1, p2, p3)); } function log(bool p0, uint256 p1, string memory p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,string,address)", p0, p1, p2, p3)); } function log(bool p0, uint256 p1, bool p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,bool,uint256)", p0, p1, p2, p3)); } function log(bool p0, uint256 p1, bool p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,bool,string)", p0, p1, p2, p3)); } function log(bool p0, uint256 p1, bool p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,bool,bool)", p0, p1, p2, p3)); } function log(bool p0, uint256 p1, bool p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,bool,address)", p0, p1, p2, p3)); } function log(bool p0, uint256 p1, address p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,address,uint256)", p0, p1, p2, p3)); } function log(bool p0, uint256 p1, address p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,address,string)", p0, p1, p2, p3)); } function log(bool p0, uint256 p1, address p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,address,bool)", p0, p1, p2, p3)); } function log(bool p0, uint256 p1, address p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,address,address)", p0, p1, p2, p3)); } function log(bool p0, string memory p1, uint256 p2, uint256 p3) internal view { _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 view { _sendLogPayload(abi.encodeWithSignature("log(bool,string,uint256,string)", p0, p1, p2, p3)); } function log(bool p0, string memory p1, uint256 p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,string,uint256,bool)", p0, p1, p2, p3)); } function log(bool p0, string memory p1, uint256 p2, address p3) internal view { _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 view { _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 view { _sendLogPayload(abi.encodeWithSignature("log(bool,string,string,string)", p0, p1, p2, p3)); } function log(bool p0, string memory p1, string memory p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,string,string,bool)", p0, p1, p2, p3)); } function log(bool p0, string memory p1, string memory p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,string,string,address)", p0, p1, p2, p3)); } function log(bool p0, string memory p1, bool p2, uint256 p3) internal view { _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 view { _sendLogPayload(abi.encodeWithSignature("log(bool,string,bool,string)", p0, p1, p2, p3)); } function log(bool p0, string memory p1, bool p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,string,bool,bool)", p0, p1, p2, p3)); } function log(bool p0, string memory p1, bool p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,string,bool,address)", p0, p1, p2, p3)); } function log(bool p0, string memory p1, address p2, uint256 p3) internal view { _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 view { _sendLogPayload(abi.encodeWithSignature("log(bool,string,address,string)", p0, p1, p2, p3)); } function log(bool p0, string memory p1, address p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,string,address,bool)", p0, p1, p2, p3)); } function log(bool p0, string memory p1, address p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,string,address,address)", p0, p1, p2, p3)); } function log(bool p0, bool p1, uint256 p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint256,uint256)", p0, p1, p2, p3)); } function log(bool p0, bool p1, uint256 p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint256,string)", p0, p1, p2, p3)); } function log(bool p0, bool p1, uint256 p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint256,bool)", p0, p1, p2, p3)); } function log(bool p0, bool p1, uint256 p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint256,address)", p0, p1, p2, p3)); } function log(bool p0, bool p1, string memory p2, uint256 p3) internal view { _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 view { _sendLogPayload(abi.encodeWithSignature("log(bool,bool,string,string)", p0, p1, p2, p3)); } function log(bool p0, bool p1, string memory p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,bool,string,bool)", p0, p1, p2, p3)); } function log(bool p0, bool p1, string memory p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,bool,string,address)", p0, p1, p2, p3)); } function log(bool p0, bool p1, bool p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool,uint256)", p0, p1, p2, p3)); } function log(bool p0, bool p1, bool p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool,string)", p0, p1, p2, p3)); } function log(bool p0, bool p1, bool p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool,bool)", p0, p1, p2, p3)); } function log(bool p0, bool p1, bool p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool,address)", p0, p1, p2, p3)); } function log(bool p0, bool p1, address p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,bool,address,uint256)", p0, p1, p2, p3)); } function log(bool p0, bool p1, address p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,bool,address,string)", p0, p1, p2, p3)); } function log(bool p0, bool p1, address p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,bool,address,bool)", p0, p1, p2, p3)); } function log(bool p0, bool p1, address p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,bool,address,address)", p0, p1, p2, p3)); } function log(bool p0, address p1, uint256 p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,address,uint256,uint256)", p0, p1, p2, p3)); } function log(bool p0, address p1, uint256 p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,address,uint256,string)", p0, p1, p2, p3)); } function log(bool p0, address p1, uint256 p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,address,uint256,bool)", p0, p1, p2, p3)); } function log(bool p0, address p1, uint256 p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,address,uint256,address)", p0, p1, p2, p3)); } function log(bool p0, address p1, string memory p2, uint256 p3) internal view { _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 view { _sendLogPayload(abi.encodeWithSignature("log(bool,address,string,string)", p0, p1, p2, p3)); } function log(bool p0, address p1, string memory p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,address,string,bool)", p0, p1, p2, p3)); } function log(bool p0, address p1, string memory p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,address,string,address)", p0, p1, p2, p3)); } function log(bool p0, address p1, bool p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,address,bool,uint256)", p0, p1, p2, p3)); } function log(bool p0, address p1, bool p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,address,bool,string)", p0, p1, p2, p3)); } function log(bool p0, address p1, bool p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,address,bool,bool)", p0, p1, p2, p3)); } function log(bool p0, address p1, bool p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,address,bool,address)", p0, p1, p2, p3)); } function log(bool p0, address p1, address p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,address,address,uint256)", p0, p1, p2, p3)); } function log(bool p0, address p1, address p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,address,address,string)", p0, p1, p2, p3)); } function log(bool p0, address p1, address p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,address,address,bool)", p0, p1, p2, p3)); } function log(bool p0, address p1, address p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,address,address,address)", p0, p1, p2, p3)); } function log(address p0, uint256 p1, uint256 p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,uint256,uint256,uint256)", p0, p1, p2, p3)); } function log(address p0, uint256 p1, uint256 p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,uint256,uint256,string)", p0, p1, p2, p3)); } function log(address p0, uint256 p1, uint256 p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,uint256,uint256,bool)", p0, p1, p2, p3)); } function log(address p0, uint256 p1, uint256 p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,uint256,uint256,address)", p0, p1, p2, p3)); } function log(address p0, uint256 p1, string memory p2, uint256 p3) internal view { _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 view { _sendLogPayload(abi.encodeWithSignature("log(address,uint256,string,string)", p0, p1, p2, p3)); } function log(address p0, uint256 p1, string memory p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,uint256,string,bool)", p0, p1, p2, p3)); } function log(address p0, uint256 p1, string memory p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,uint256,string,address)", p0, p1, p2, p3)); } function log(address p0, uint256 p1, bool p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,uint256,bool,uint256)", p0, p1, p2, p3)); } function log(address p0, uint256 p1, bool p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,uint256,bool,string)", p0, p1, p2, p3)); } function log(address p0, uint256 p1, bool p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,uint256,bool,bool)", p0, p1, p2, p3)); } function log(address p0, uint256 p1, bool p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,uint256,bool,address)", p0, p1, p2, p3)); } function log(address p0, uint256 p1, address p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,uint256,address,uint256)", p0, p1, p2, p3)); } function log(address p0, uint256 p1, address p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,uint256,address,string)", p0, p1, p2, p3)); } function log(address p0, uint256 p1, address p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,uint256,address,bool)", p0, p1, p2, p3)); } function log(address p0, uint256 p1, address p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,uint256,address,address)", p0, p1, p2, p3)); } function log(address p0, string memory p1, uint256 p2, uint256 p3) internal view { _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 view { _sendLogPayload(abi.encodeWithSignature("log(address,string,uint256,string)", p0, p1, p2, p3)); } function log(address p0, string memory p1, uint256 p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,string,uint256,bool)", p0, p1, p2, p3)); } function log(address p0, string memory p1, uint256 p2, address p3) internal view { _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 view { _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 view { _sendLogPayload(abi.encodeWithSignature("log(address,string,string,string)", p0, p1, p2, p3)); } function log(address p0, string memory p1, string memory p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,string,string,bool)", p0, p1, p2, p3)); } function log(address p0, string memory p1, string memory p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,string,string,address)", p0, p1, p2, p3)); } function log(address p0, string memory p1, bool p2, uint256 p3) internal view { _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 view { _sendLogPayload(abi.encodeWithSignature("log(address,string,bool,string)", p0, p1, p2, p3)); } function log(address p0, string memory p1, bool p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,string,bool,bool)", p0, p1, p2, p3)); } function log(address p0, string memory p1, bool p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,string,bool,address)", p0, p1, p2, p3)); } function log(address p0, string memory p1, address p2, uint256 p3) internal view { _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 view { _sendLogPayload(abi.encodeWithSignature("log(address,string,address,string)", p0, p1, p2, p3)); } function log(address p0, string memory p1, address p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,string,address,bool)", p0, p1, p2, p3)); } function log(address p0, string memory p1, address p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,string,address,address)", p0, p1, p2, p3)); } function log(address p0, bool p1, uint256 p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,bool,uint256,uint256)", p0, p1, p2, p3)); } function log(address p0, bool p1, uint256 p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,bool,uint256,string)", p0, p1, p2, p3)); } function log(address p0, bool p1, uint256 p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,bool,uint256,bool)", p0, p1, p2, p3)); } function log(address p0, bool p1, uint256 p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,bool,uint256,address)", p0, p1, p2, p3)); } function log(address p0, bool p1, string memory p2, uint256 p3) internal view { _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 view { _sendLogPayload(abi.encodeWithSignature("log(address,bool,string,string)", p0, p1, p2, p3)); } function log(address p0, bool p1, string memory p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,bool,string,bool)", p0, p1, p2, p3)); } function log(address p0, bool p1, string memory p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,bool,string,address)", p0, p1, p2, p3)); } function log(address p0, bool p1, bool p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,bool,bool,uint256)", p0, p1, p2, p3)); } function log(address p0, bool p1, bool p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,bool,bool,string)", p0, p1, p2, p3)); } function log(address p0, bool p1, bool p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,bool,bool,bool)", p0, p1, p2, p3)); } function log(address p0, bool p1, bool p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,bool,bool,address)", p0, p1, p2, p3)); } function log(address p0, bool p1, address p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,bool,address,uint256)", p0, p1, p2, p3)); } function log(address p0, bool p1, address p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,bool,address,string)", p0, p1, p2, p3)); } function log(address p0, bool p1, address p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,bool,address,bool)", p0, p1, p2, p3)); } function log(address p0, bool p1, address p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,bool,address,address)", p0, p1, p2, p3)); } function log(address p0, address p1, uint256 p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,address,uint256,uint256)", p0, p1, p2, p3)); } function log(address p0, address p1, uint256 p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,address,uint256,string)", p0, p1, p2, p3)); } function log(address p0, address p1, uint256 p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,address,uint256,bool)", p0, p1, p2, p3)); } function log(address p0, address p1, uint256 p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,address,uint256,address)", p0, p1, p2, p3)); } function log(address p0, address p1, string memory p2, uint256 p3) internal view { _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 view { _sendLogPayload(abi.encodeWithSignature("log(address,address,string,string)", p0, p1, p2, p3)); } function log(address p0, address p1, string memory p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,address,string,bool)", p0, p1, p2, p3)); } function log(address p0, address p1, string memory p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,address,string,address)", p0, p1, p2, p3)); } function log(address p0, address p1, bool p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,address,bool,uint256)", p0, p1, p2, p3)); } function log(address p0, address p1, bool p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,address,bool,string)", p0, p1, p2, p3)); } function log(address p0, address p1, bool p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,address,bool,bool)", p0, p1, p2, p3)); } function log(address p0, address p1, bool p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,address,bool,address)", p0, p1, p2, p3)); } function log(address p0, address p1, address p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,address,address,uint256)", p0, p1, p2, p3)); } function log(address p0, address p1, address p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,address,address,string)", p0, p1, p2, p3)); } function log(address p0, address p1, address p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,address,address,bool)", p0, p1, p2, p3)); } function log(address p0, address p1, address p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,address,address,address)", p0, p1, p2, p3)); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol) pragma solidity ^0.8.0; /** * @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); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol) pragma solidity ^0.8.0; import "../IERC20.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); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-IERC20Permit.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612]. * * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't * need to send a transaction, and thus is not required to hold Ether at all. */ interface IERC20Permit { /** * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens, * given ``owner``'s signed approval. * * IMPORTANT: The same issues {IERC20-approve} has related to transaction * ordering also apply here. * * Emits an {Approval} event. * * Requirements: * * - `spender` cannot be the zero address. * - `deadline` must be a timestamp in the future. * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner` * over the EIP712-formatted function arguments. * - the signature must use ``owner``'s current nonce (see {nonces}). * * For more information on the signature format, see the * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP * section]. */ function permit( address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) external; /** * @dev Returns the current nonce for `owner`. This value must be * included whenever a signature is generated for {permit}. * * Every successful call to {permit} increases ``owner``'s nonce by one. This * prevents a signature from being used multiple times. */ function nonces(address owner) external view returns (uint256); /** * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}. */ // solhint-disable-next-line func-name-mixedcase function DOMAIN_SEPARATOR() external view returns (bytes32); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/utils/SafeERC20.sol) pragma solidity ^0.8.0; import "../IERC20.sol"; import "../extensions/draft-IERC20Permit.sol"; import "../../../utils/Address.sol"; /** * @title SafeERC20 * @dev Wrappers around ERC20 operations that throw on failure (when the token * contract returns false). Tokens that return no value (and instead revert or * throw on failure) are also supported, non-reverting calls are assumed to be * successful. * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract, * which allows you to call the safe operations as `token.safeTransfer(...)`, etc. */ library SafeERC20 { using Address for address; function safeTransfer( IERC20 token, address to, uint256 value ) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value)); } function safeTransferFrom( IERC20 token, address from, address to, uint256 value ) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value)); } /** * @dev Deprecated. This function has issues similar to the ones found in * {IERC20-approve}, and its usage is discouraged. * * Whenever possible, use {safeIncreaseAllowance} and * {safeDecreaseAllowance} instead. */ function safeApprove( IERC20 token, address spender, uint256 value ) internal { // safeApprove should only be called when setting an initial allowance, // or when resetting it to zero. To increase and decrease it, use // 'safeIncreaseAllowance' and 'safeDecreaseAllowance' require( (value == 0) || (token.allowance(address(this), spender) == 0), "SafeERC20: approve from non-zero to non-zero allowance" ); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value)); } function safeIncreaseAllowance( IERC20 token, address spender, uint256 value ) internal { uint256 newAllowance = token.allowance(address(this), spender) + value; _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } function safeDecreaseAllowance( IERC20 token, address spender, uint256 value ) internal { unchecked { uint256 oldAllowance = token.allowance(address(this), spender); require(oldAllowance >= value, "SafeERC20: decreased allowance below zero"); uint256 newAllowance = oldAllowance - value; _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } } function safePermit( IERC20Permit token, address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) internal { uint256 nonceBefore = token.nonces(owner); token.permit(owner, spender, value, deadline, v, r, s); uint256 nonceAfter = token.nonces(owner); require(nonceAfter == nonceBefore + 1, "SafeERC20: permit did not succeed"); } /** * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement * on the return value: the return value is optional (but if data is returned, it must not be false). * @param token The token targeted by the call. * @param data The call data (encoded using abi.encode or one of its variants). */ function _callOptionalReturn(IERC20 token, bytes memory data) private { // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that // the target address contains contract code and also asserts for success in the low-level call. bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed"); if (returndata.length > 0) { // Return data is optional require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed"); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol) pragma solidity ^0.8.1; /** * @dev Collection of functions related to the address type */ library Address { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * ==== * * [IMPORTANT] * ==== * You shouldn't rely on `isContract` to protect against flash loan attacks! * * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract * constructor. * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize/address.code.length, which returns 0 // for contracts in construction, since the code is only stored at the end // of the constructor execution. return account.code.length > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://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 functionCallWithValue(target, data, 0, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value ) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value, string memory errorMessage ) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall( address target, bytes memory data, string memory errorMessage ) internal view returns (bytes memory) { (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { return functionDelegateCall(target, data, "Address: low-level delegate call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract. * * _Available since v4.8._ */ function verifyCallResultFromTarget( address target, bool success, bytes memory returndata, string memory errorMessage ) internal view returns (bytes memory) { if (success) { if (returndata.length == 0) { // only check isContract if the call was successful and the return data is empty // otherwise we already know that it was a contract require(isContract(target), "Address: call to non-contract"); } return returndata; } else { _revert(returndata, errorMessage); } } /** * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason or using the provided one. * * _Available since v4.3._ */ function verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) internal pure returns (bytes memory) { if (success) { return returndata; } else { _revert(returndata, errorMessage); } } function _revert(bytes memory returndata, string memory errorMessage) private pure { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly /// @solidity memory-safe-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/Context.sol) pragma solidity ^0.8.0; /** * @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; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (utils/math/Math.sol) pragma solidity ^0.8.0; /** * @dev Standard math utilities missing in the Solidity language. */ library Math { enum Rounding { Down, // Toward negative infinity Up, // Toward infinity Zero // Toward zero } /** * @dev Returns the largest of two numbers. */ function max(uint256 a, uint256 b) internal pure returns (uint256) { return a >= b ? a : b; } /** * @dev Returns the smallest of two numbers. */ function min(uint256 a, uint256 b) internal pure returns (uint256) { return a < b ? a : b; } /** * @dev Returns the average of two numbers. The result is rounded towards * zero. */ function average(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b) / 2 can overflow. return (a & b) + (a ^ b) / 2; } /** * @dev Returns the ceiling of the division of two numbers. * * This differs from standard division with `/` in that it rounds up instead * of rounding down. */ function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b - 1) / b can overflow on addition, so we distribute. return a == 0 ? 0 : (a - 1) / b + 1; } /** * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0 * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv) * with further edits by Uniswap Labs also under MIT license. */ function mulDiv( uint256 x, uint256 y, uint256 denominator ) internal pure returns (uint256 result) { unchecked { // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256 // variables such that product = prod1 * 2^256 + prod0. uint256 prod0; // Least significant 256 bits of the product uint256 prod1; // Most significant 256 bits of the product assembly { let mm := mulmod(x, y, not(0)) prod0 := mul(x, y) prod1 := sub(sub(mm, prod0), lt(mm, prod0)) } // Handle non-overflow cases, 256 by 256 division. if (prod1 == 0) { return prod0 / denominator; } // Make sure the result is less than 2^256. Also prevents denominator == 0. require(denominator > prod1); /////////////////////////////////////////////// // 512 by 256 division. /////////////////////////////////////////////// // Make division exact by subtracting the remainder from [prod1 prod0]. uint256 remainder; assembly { // Compute remainder using mulmod. remainder := mulmod(x, y, denominator) // Subtract 256 bit number from 512 bit number. prod1 := sub(prod1, gt(remainder, prod0)) prod0 := sub(prod0, remainder) } // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1. // See https://cs.stackexchange.com/q/138556/92363. // Does not overflow because the denominator cannot be zero at this stage in the function. uint256 twos = denominator & (~denominator + 1); assembly { // Divide denominator by twos. denominator := div(denominator, twos) // Divide [prod1 prod0] by twos. prod0 := div(prod0, twos) // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one. twos := add(div(sub(0, twos), twos), 1) } // Shift in bits from prod1 into prod0. prod0 |= prod1 * twos; // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for // four bits. That is, denominator * inv = 1 mod 2^4. uint256 inverse = (3 * denominator) ^ 2; // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works // in modular arithmetic, doubling the correct bits in each step. inverse *= 2 - denominator * inverse; // inverse mod 2^8 inverse *= 2 - denominator * inverse; // inverse mod 2^16 inverse *= 2 - denominator * inverse; // inverse mod 2^32 inverse *= 2 - denominator * inverse; // inverse mod 2^64 inverse *= 2 - denominator * inverse; // inverse mod 2^128 inverse *= 2 - denominator * inverse; // inverse mod 2^256 // Because the division is now exact we can divide by multiplying with the modular inverse of denominator. // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1 // is no longer required. result = prod0 * inverse; return result; } } /** * @notice Calculates x * y / denominator with full precision, following the selected rounding direction. */ function mulDiv( uint256 x, uint256 y, uint256 denominator, Rounding rounding ) internal pure returns (uint256) { uint256 result = mulDiv(x, y, denominator); if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) { result += 1; } return result; } /** * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down. * * Inspired by Henry S. Warren, Jr.'s "Hacker's Delight" (Chapter 11). */ function sqrt(uint256 a) internal pure returns (uint256) { if (a == 0) { return 0; } // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target. // We know that the "msb" (most significant bit) of our target number `a` is a power of 2 such that we have // `msb(a) <= a < 2*msb(a)`. // We also know that `k`, the position of the most significant bit, is such that `msb(a) = 2**k`. // This gives `2**k < a <= 2**(k+1)` → `2**(k/2) <= sqrt(a) < 2 ** (k/2+1)`. // Using an algorithm similar to the msb computation, we are able to compute `result = 2**(k/2)` which is a // good first approximation of `sqrt(a)` with at least 1 correct bit. uint256 result = 1; uint256 x = a; if (x >> 128 > 0) { x >>= 128; result <<= 64; } if (x >> 64 > 0) { x >>= 64; result <<= 32; } if (x >> 32 > 0) { x >>= 32; result <<= 16; } if (x >> 16 > 0) { x >>= 16; result <<= 8; } if (x >> 8 > 0) { x >>= 8; result <<= 4; } if (x >> 4 > 0) { x >>= 4; result <<= 2; } if (x >> 2 > 0) { result <<= 1; } // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128, // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision // into the expected uint128 result. unchecked { result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; return min(result, a / result); } } /** * @notice Calculates sqrt(a), following the selected rounding direction. */ function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) { uint256 result = sqrt(a); if (rounding == Rounding.Up && result * result < a) { result += 1; } return result; } }
// SPDX-License-Identifier: GPL-3.0-or-later pragma solidity >=0.6.0; // helper methods for interacting with ERC20 tokens and sending ETH that do not consistently return true/false library TransferHelper { 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::safeApprove: approve failed' ); } 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::safeTransfer: transfer failed' ); } 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::transferFrom: transferFrom failed' ); } function safeTransferETH(address to, uint256 value) internal { (bool success, ) = to.call{value: value}(new bytes(0)); require(success, 'TransferHelper::safeTransferETH: ETH transfer failed'); } }
pragma solidity ^0.8.3; import "@openzeppelin/contracts/utils/Context.sol"; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import "@uniswap/lib/contracts/libraries/TransferHelper.sol"; import "./ITranche.sol"; struct TrancheData { ITranche token; uint256 ratio; } /** * @dev Controller for a ButtonTranche bond system */ interface IBondController { event Deposit(address from, uint256 amount, uint256 feeBps); event Mature(address caller); event RedeemMature(address user, address tranche, uint256 amount); event Redeem(address user, uint256[] amounts); event FeeUpdate(uint256 newFee); function collateralToken() external view returns (address); function tranches(uint256 i) external view returns (ITranche token, uint256 ratio); function trancheCount() external view returns (uint256 count); function feeBps() external view returns (uint256 fee); function maturityDate() external view returns (uint256 maturityDate); function isMature() external view returns (bool isMature); function creationDate() external view returns (uint256 creationDate); function totalDebt() external view returns (uint256 totalDebt); /** * @dev Deposit `amount` tokens from `msg.sender`, get tranche tokens in return * Requirements: * - `msg.sender` must have `approved` `amount` collateral tokens to this contract */ function deposit(uint256 amount) external; /** * @dev Matures the bond. Disables deposits, * fixes the redemption ratio, and distributes collateral to redemption pools * Redeems any fees collected from deposits, sending redeemed funds to the contract owner * Requirements: * - The bond is not already mature * - One of: * - `msg.sender` is owner * - `maturityDate` has passed */ function mature() external; /** * @dev Redeems some tranche tokens * Requirements: * - The bond is mature * - `msg.sender` owns at least `amount` tranche tokens from address `tranche` * - `tranche` must be a valid tranche token on this bond */ function redeemMature(address tranche, uint256 amount) external; /** * @dev Redeems a slice of tranche tokens from all tranches. * Returns collateral to the user proportionally to the amount of debt they are removing * Requirements * - The bond is not mature * - The number of `amounts` is the same as the number of tranches * - The `amounts` are in equivalent ratio to the tranche order */ function redeem(uint256[] memory amounts) external; /** * @dev Updates the fee taken on deposit to the given new fee * * Requirements * - `msg.sender` has admin role * - `newFeeBps` is in range [0, 50] */ function setFee(uint256 newFeeBps) external; }
pragma solidity ^0.8.3; import "@openzeppelin/contracts/utils/Context.sol"; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import "@uniswap/lib/contracts/libraries/TransferHelper.sol"; /** * @dev ERC20 token to represent a single tranche for a ButtonTranche bond * */ interface ITranche is IERC20 { /** * @dev returns the BondController address which owns this Tranche contract * It should have admin permissions to call mint, burn, and redeem functions */ function bond() external view returns (address); /** * @dev Mint `amount` tokens to `to` * Only callable by the owner (bond controller). Used to * manage bonds, specifically creating tokens upon deposit * @param to the address to mint tokens to * @param amount The amount of tokens to mint */ function mint(address to, uint256 amount) external; /** * @dev Burn `amount` tokens from `from`'s balance * Only callable by the owner (bond controller). Used to * manage bonds, specifically burning tokens upon redemption * @param from The address to burn tokens from * @param amount The amount of tokens to burn */ function burn(address from, uint256 amount) external; /** * @dev Burn `amount` tokens from `from` and return the proportional * value of the collateral token to `to` * @param from The address to burn tokens from * @param to The address to send collateral back to * @param amount The amount of tokens to burn */ function redeem( address from, address to, uint256 amount ) external; }
//SPDX-License-Identifier: Unlicense pragma solidity 0.8.13; import "../../utils/ICBBImmutableArgs.sol"; /** * @dev Convertible Bond Box for a ButtonTranche bond */ interface IConvertibleBondBox is ICBBImmutableArgs { event Lend( address caller, address borrower, address lender, uint256 stableAmount, uint256 price ); event Borrow( address caller, address borrower, address lender, uint256 stableAmount, uint256 price ); event RedeemStable(address caller, uint256 safeSlipAmount, uint256 price); event RedeemSafeTranche(address caller, uint256 safeSlipAmount); event RedeemRiskTranche(address caller, uint256 riskSlipAmount); event Repay( address caller, uint256 stablesPaid, uint256 riskTranchePayout, uint256 price ); event Initialized(address owner); event ReInitialized(uint256 initialPrice, uint256 timestamp); event FeeUpdate(uint256 newFee); error PenaltyTooHigh(uint256 given, uint256 maxPenalty); error BondIsMature(uint256 currentTime, uint256 maturity); error InitialPriceTooHigh(uint256 given, uint256 maxPrice); error InitialPriceIsZero(uint256 given, uint256 maxPrice); error ConvertibleBondBoxNotStarted(uint256 given, uint256 minStartDate); error BondNotMatureYet(uint256 maturityDate, uint256 currentTime); error MinimumInput(uint256 input, uint256 reqInput); error FeeTooLarge(uint256 input, uint256 maximum); //Need to add getters for state variables /** * @dev Sets startdate to be block.timestamp, sets initialPrice, and takes initial atomic deposit * @param _initialPrice the initialPrice for the CBB * Requirements: * - `msg.sender` is owner */ function reinitialize(uint256 _initialPrice) external; /** * @dev Lends StableTokens for SafeSlips when provided with matching borrow collateral * @param _borrower The address to send the RiskSlip and StableTokens to * @param _lender The address to send the SafeSlips to * @param _stableAmount The amount of StableTokens to lend * Requirements: * - `msg.sender` must have `approved` `_stableAmount` stable tokens to this contract - CBB must be reinitialized */ function lend( address _borrower, address _lender, uint256 _stableAmount ) external; /** * @dev Borrows with tranches of CollateralTokens when provided with a matching amount of StableTokens * Collateral tokens get tranched and any non-convertible bond box tranches get sent back to borrower * @param _borrower The address to send the RiskSlip and StableTokens to * @param _lender The address to send the SafeSlips to * @param _safeTrancheAmount The amount of SafeTranche being borrowed against * Requirements: * - `msg.sender` must have `approved` appropriate amount of tranches of tokens to this contract - CBB must be reinitialized - must be enough stable tokens inside convertible bond box to borrow */ function borrow( address _borrower, address _lender, uint256 _safeTrancheAmount ) external; /** * @dev returns time-weighted current price for SafeSlip, with final price as $1.00 at maturity */ function currentPrice() external view returns (uint256); /** * @dev allows repayment of loan in exchange for proportional amount of SafeTranche and Z-tranche * @param _stableAmount The amount of stable-Tokens to repay with * Requirements: * - `msg.sender` must have `approved` `stableAmount` of stable tokens to this contract */ function repay(uint256 _stableAmount) external; /** * @dev allows repayment of loan in exchange for proportional amount of SafeTranche and Z-tranche * @param _riskSlipAmount The amount of riskSlips to be repaid * Requirements: * - `msg.sender` must have `approved` appropriate amount of stable tokens to this contract */ function repayMax(uint256 _riskSlipAmount) external; /** * @dev allows lender to redeem SafeSlips for SafeTranches * @param _safeSlipAmount The amount of safe-slips to redeem * Requirements: * - can only be called after Bond is Mature * - `msg.sender` must have `approved` `safeSlipAmount` of SafeSlip tokens to this contract */ function redeemSafeTranche(uint256 _safeSlipAmount) external; /** * @dev allows borrower to redeem RiskSlips for tranches (i.e. default) * @param _riskSlipAmount The amount of RiskSlips to redeem * Requirements: * - can only be called after Bond is Mature * - `msg.sender` must have `approved` `_riskSlipAmount` of RiskSlip tokens to this contract */ function redeemRiskTranche(uint256 _riskSlipAmount) external; /** * @dev allows lender to redeem SafeSlips for StableTokens * @param _safeSlipAmount The amount of SafeSlips to redeem * Requirements: * - `msg.sender` must have `approved` `safeSlipAmount` of safe-Slip tokens to this contract * - can only be called when StableTokens are present inside CBB */ function redeemStable(uint256 _safeSlipAmount) external; /** * @dev Updates the fee taken on redeem/repay to the given new fee * * Requirements * - `msg.sender` has admin role * - `newFeeBps` is in range [0, 50] */ function setFee(uint256 newFeeBps) external; /** * @dev Gets the start date */ function s_startDate() external view returns (uint256); /** * @dev Gets the total repaid safe slips to date */ function s_repaidSafeSlips() external view returns (uint256); /** * @dev Gets the tranche granularity constant */ function s_trancheGranularity() external view returns (uint256); /** * @dev Gets the penalty granularity constant */ function s_penaltyGranularity() external view returns (uint256); /** * @dev Gets the price granularity constant */ function s_priceGranularity() external view returns (uint256); /** * @dev Gets the fee basis points */ function feeBps() external view returns (uint256); /** * @dev Gets the basis points denominator constant. AKA a fee granularity constant */ function BPS() external view returns (uint256); /** * @dev Gets the max fee basis points constant. */ function maxFeeBPS() external view returns (uint256); /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) external; /** * @dev Gets the initialPrice of SafeSlip. */ function s_initialPrice() external view returns (uint256); }
pragma solidity 0.8.13; import "@openzeppelin/contracts/utils/Context.sol"; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; /** * @dev ERC20 token to represent a single slip for a bond box * */ interface ISlip is IERC20 { event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev returns the bond box address which owns this slip contract * It should have admin permissions to call mint, burn, and redeem functions */ function boxOwner() external view returns (address); /** * @dev Mint `amount` tokens to `to` * Only callable by the owner. * @param to the address to mint tokens to * @param amount The amount of tokens to mint */ function mint(address to, uint256 amount) external; /** * @dev Burn `amount` tokens from `from`'s balance * Only callable by the owner. * @param from The address to burn tokens from * @param amount The amount of tokens to burn */ function burn(address from, uint256 amount) external; /** * @dev allows owner to transfer ownership to a new owner. Implemented so that factory can transfer minting/burning ability to CBB after deployment * @param newOwner The address of the CBB */ function changeOwner(address newOwner) external; }
// SPDX-License-Identifier: UNLICENSED pragma solidity 0.8.13; import "../../utils/ISBImmutableArgs.sol"; interface IStagingBox is ISBImmutableArgs { event LendDeposit(address lender, uint256 lendAmount); event BorrowDeposit(address borrower, uint256 safeTrancheAmount); event LendWithdrawal(address lender, uint256 lendSlipAmount); event BorrowWithdrawal(address borrower, uint256 borrowSlipAmount); event RedeemBorrowSlip(address caller, uint256 borrowSlipAmount); event RedeemLendSlip(address caller, uint256 lendSlipAmount); event Initialized(address owner); error InitialPriceTooHigh(uint256 given, uint256 maxPrice); error InitialPriceIsZero(uint256 given, uint256 maxPrice); error WithdrawAmountTooHigh(uint256 requestAmount, uint256 maxAmount); error CBBReinitialized(bool state, bool requiredState); function s_reinitLendAmount() external view returns (uint256); /** * @dev Deposits collateral for BorrowSlips * @param _borrower The recipent address of the BorrowSlips * @param _borrowAmount The amount of stableTokens to be borrowed * Requirements: * - `msg.sender` must have `approved` `stableAmount` stable tokens to this contract */ function depositBorrow(address _borrower, uint256 _borrowAmount) external; /** * @dev deposit _lendAmount of stable-tokens for LendSlips * @param _lender The recipent address of the LenderSlips * @param _lendAmount The amount of stable tokens to deposit * Requirements: * - `msg.sender` must have `approved` `stableAmount` stable tokens to this contract */ function depositLend(address _lender, uint256 _lendAmount) external; /** * @dev Burns BorrowSlips for Collateral * @param _borrowSlipAmount The amount of borrowSlips to withdraw * Requirements: */ function withdrawBorrow(uint256 _borrowSlipAmount) external; /** * @dev burns LendSlips for Stables * @param _lendSlipAmount The amount of stable tokens to withdraw * Requirements: * - Cannot withdraw more than s_reinitLendAmount after reinitialization */ function withdrawLend(uint256 _lendSlipAmount) external; /** * @dev Exchanges BorrowSlips for RiskSlips + Stablecoin loan * @param _borrowSlipAmount amount of BorrowSlips to redeem RiskSlips and USDT with * Requirements: */ function redeemBorrowSlip(uint256 _borrowSlipAmount) external; /** * @dev Exchanges lendSlips for safeSlips * @param _lendSlipAmount amount of LendSlips to redeem SafeSlips with * Requirements: */ function redeemLendSlip(uint256 _lendSlipAmount) external; /** * @dev Transmits the the Reinitialization to the CBB * @param _lendOrBorrow boolean to indicate whether to initial deposit should be a 'borrow' or a 'lend' * Requirements: * - StagingBox must be the owner of the CBB to call this function * - Change owner of CBB to be the SB prior to calling this function if not already done */ function transmitReInit(bool _lendOrBorrow) external; /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) external; /** * @dev Transfers ownership of the CBB contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferCBBOwnership(address newOwner) external; }
// SPDX-License-Identifier: UNLICENSED pragma solidity 0.8.13; import "../interfaces/IStagingBox.sol"; interface IStagingLoanRouter { error SlippageExceeded(uint256 expectedAmount, uint256 minAmount); /** * @dev Wraps and tranches raw token and then deposits into staging box for a simple underlying bond (A/Z) * @param _stagingBox The staging box tied to the Convertible Bond * @param _amountRaw The amount of SafeTranche tokens to borrow against * @param _minBorrowSlips The minimum expected borrowSlips for slippage protection * Requirements: * - `msg.sender` must have `approved` `_amountRaw` collateral tokens to this contract */ function simpleWrapTrancheBorrow( IStagingBox _stagingBox, uint256 _amountRaw, uint256 _minBorrowSlips ) external; /** * @dev Wraps and tranches raw token and then deposits into staging box for any underlying bond * @param _stagingBox The staging box tied to the Convertible Bond * @param _amountRaw The amount of SafeTranche tokens to borrow against * @param _minBorrowSlips The minimum expected borrowSlips for slippage protection * Requirements: * - `msg.sender` must have `approved` `_amountRaw` collateral tokens to this contract */ function multiWrapTrancheBorrow( IStagingBox _stagingBox, uint256 _amountRaw, uint256 _minBorrowSlips ) external; /** * @dev withdraws borrowSlip and redeems w/ simple underlying bond (A/Z) * @param _stagingBox The staging box tied to the Convertible Bond * @param _borrowSlipAmount The amount of borrowSlips to be withdrawn * Requirements: * - `msg.sender` must have `approved` `_borrowSlipAmount` BorrowSlip tokens to this contract */ function simpleWithdrawBorrowUnwrap( IStagingBox _stagingBox, uint256 _borrowSlipAmount ) external; /** * @dev redeems lendSlips for safeSlips and safeSlips for stables * @param _stagingBox The staging box tied to the Convertible Bond * @param _lendSlipAmount The amount of lendSlips to be redeemed * Requirements: * - can only be called when there are stables in the CBB to be repaid */ function redeemLendSlipsForStables( IStagingBox _stagingBox, uint256 _lendSlipAmount ) external; /** * @dev redeems safeSlips for tranches, redeems tranches for rebasing collateral, unwraps rebasing collateral, and then swaps for stableToken * @param _stagingBox The staging box tied to the Convertible Bond * @param _safeSlipAmount The amount of lendSlips to be redeemed * Requirements: * - can only be called after maturity */ function redeemSafeSlipsForTranchesAndUnwrap( IStagingBox _stagingBox, uint256 _safeSlipAmount ) external; /** * @dev redeems lendSlips for safeSlips and safeSlips for tranches, redeems tranches for rebasing collateral, unwraps rebasing collateral, and then swaps for stableToken * @param _stagingBox The staging box tied to the Convertible Bond * @param _lendSlipAmount The amount of lendSlips to be redeemed * Requirements: * - can only be called after maturity */ function redeemLendSlipsForTranchesAndUnwrap( IStagingBox _stagingBox, uint256 _lendSlipAmount ) external; /** * @dev redeems riskSlips for riskTranches, redeems tranches for rebasing collateral, unwraps rebasing collateral * @param _stagingBox The staging box tied to the Convertible Bond * @param _riskSlipAmount The amount of riskSlips to be redeemed * Requirements: * - can only be called after maturity */ function redeemRiskSlipsForTranchesAndUnwrap( IStagingBox _stagingBox, uint256 _riskSlipAmount ) external; /** * @dev repays stable tokens to CBB and unwraps collateral into underlying * @param _stagingBox The staging box tied to the Convertible Bond * @param _stableAmount The amount of stableTokens to be repaid * @param _stableFees The amount of stableToken fees * @param _riskSlipAmount The amount of riskSlips to be repaid with * Requirements: * - can only be called prior to maturity * - only to be called with bonds that have A/Z tranche setup */ function repayAndUnwrapSimple( IStagingBox _stagingBox, uint256 _stableAmount, uint256 _stableFees, uint256 _riskSlipAmount ) external; /** * @dev repays of users riskSlips w/ stable tokens to CBB and unwraps collateral into underlying * @param _stagingBox The staging box tied to the Convertible Bond * @param _stableAmount The amount of stableTokens to be repaid * @param _stableFees The amount of stableToken fees * @param _riskSlipAmount The amount of risk slips being repaid for * Requirements: * - can only be called prior to maturity * - only to be called with bonds that have A/Z tranche setup */ function repayMaxAndUnwrapSimple( IStagingBox _stagingBox, uint256 _stableAmount, uint256 _stableFees, uint256 _riskSlipAmount ) external; /** * @dev repays stable tokens to CBB and unwraps collateral into underlying * @param _stagingBox The staging box tied to the Convertible Bond * @param _stableAmount The amount of stableTokens to be repaid * @param _stableFees The amount of stableToken fees * @param _riskSlipAmount The amount of riskSlips to be repaid with * Requirements: * - can only be called after maturity */ function repayAndUnwrapMature( IStagingBox _stagingBox, uint256 _stableAmount, uint256 _stableFees, uint256 _riskSlipAmount ) external; }
// SPDX-License-Identifier: UNLICENSED pragma solidity 0.8.13; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import "../src/interfaces/ISlip.sol"; import "@buttonwood-protocol/tranche/contracts/interfaces/IBondController.sol"; interface ICBBImmutableArgs { /** * @notice The bond that holds the tranches * @dev using ClonesWithImmutableArgs pattern here to save gas * @dev https://github.com/wighawag/clones-with-immutable-args * @return The underlying buttonwood bond */ function bond() external pure returns (IBondController); /** * @notice The safeSlip object * @dev using ClonesWithImmutableArgs pattern here to save gas * @dev https://github.com/wighawag/clones-with-immutable-args * @return The safeSlip Slip object */ function safeSlip() external pure returns (ISlip); /** * @notice The riskSlip object * @dev using ClonesWithImmutableArgs pattern here to save gas * @dev https://github.com/wighawag/clones-with-immutable-args * @return The riskSlip Slip object */ function riskSlip() external pure returns (ISlip); /** * @notice penalty for zslips * @dev using ClonesWithImmutableArgs pattern here to save gas * @dev https://github.com/wighawag/clones-with-immutable-args * @return The penalty ratio */ function penalty() external pure returns (uint256); /** * @notice The rebasing collateral token used to make bonds * @dev using ClonesWithImmutableArgs pattern here to save gas * @dev https://github.com/wighawag/clones-with-immutable-args * @return The rebasing collateral token object */ function collateralToken() external pure returns (IERC20); /** * @notice The stable token used to buy bonds * @dev using ClonesWithImmutableArgs pattern here to save gas * @dev https://github.com/wighawag/clones-with-immutable-args * @return The stable token object */ function stableToken() external pure returns (IERC20); /** * @notice The tranche index used to pick a safe tranche * @dev using ClonesWithImmutableArgs pattern here to save gas * @dev https://github.com/wighawag/clones-with-immutable-args * @return The index representing the tranche */ function trancheIndex() external pure returns (uint256); /** * @notice The maturity date of the underlying buttonwood bond * @dev using ClonesWithImmutableArgs pattern here to save gas * @dev https://github.com/wighawag/clones-with-immutable-args * @return The timestamp for the bond maturity */ function maturityDate() external pure returns (uint256); /** * @notice The safeTranche of the Convertible Bond Box * @dev using ClonesWithImmutableArgs pattern here to save gas * @dev https://github.com/wighawag/clones-with-immutable-args * @return The safeTranche tranche object */ function safeTranche() external pure returns (ITranche); /** * @notice The tranche ratio of the safeTranche * @dev using ClonesWithImmutableArgs pattern here to save gas * @dev https://github.com/wighawag/clones-with-immutable-args * @return The tranche ratio of the safeTranche */ function safeRatio() external pure returns (uint256); /** * @notice The riskTranche of the Convertible Bond Box * @dev using ClonesWithImmutableArgs pattern here to save gas * @dev https://github.com/wighawag/clones-with-immutable-args * @return The riskTranche tranche object */ function riskTranche() external pure returns (ITranche); /** * @notice The tranche ratio of the riskTranche * @dev using ClonesWithImmutableArgs pattern here to save gas * @dev https://github.com/wighawag/clones-with-immutable-args * @return The tranche ratio of the riskTranche */ function riskRatio() external pure returns (uint256); /** * @notice The decimals of tranche-tokens * @dev using ClonesWithImmutableArgs pattern here to save gas * @dev https://github.com/wighawag/clones-with-immutable-args * @return The decimals of tranche-tokens */ function trancheDecimals() external pure returns (uint256); /** * @notice The decimals of stable-tokens * @dev using ClonesWithImmutableArgs pattern here to save gas * @dev https://github.com/wighawag/clones-with-immutable-args * @return The decimals of stable-tokens */ function stableDecimals() external pure returns (uint256); }
// SPDX-License-Identifier: UNLICENSED pragma solidity 0.8.13; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import "../src/interfaces/IConvertibleBondBox.sol"; interface ISBImmutableArgs { /** * @notice the lend slip object * @dev using ClonesWithImmutableArgs pattern here to save gas * @dev https://github.com/wighawag/clones-with-immutable-args * @return The lend slip object */ function lendSlip() external pure returns (ISlip); /** * @notice the borrow slip object * @dev using ClonesWithImmutableArgs pattern here to save gas * @dev https://github.com/wighawag/clones-with-immutable-args * @return The borrowSlip object */ function borrowSlip() external pure returns (ISlip); /** * @notice The convertible bond box object * @dev using ClonesWithImmutableArgs pattern here to save gas * @dev https://github.com/wighawag/clones-with-immutable-args * @return The convertible bond box object */ function convertibleBondBox() external pure returns (IConvertibleBondBox); /** * @notice The cnnvertible bond box object * @dev using ClonesWithImmutableArgs pattern here to save gas * @dev https://github.com/wighawag/clones-with-immutable-args * @return The convertible bond box object */ function initialPrice() external pure returns (uint256); /** * @notice The stable token used to buy bonds * @dev using ClonesWithImmutableArgs pattern here to save gas * @dev https://github.com/wighawag/clones-with-immutable-args * @return The stable token object */ function stableToken() external pure returns (IERC20); /** * @notice The safeTranche of the CBB * @dev using ClonesWithImmutableArgs pattern here to save gas * @dev https://github.com/wighawag/clones-with-immutable-args * @return The safeTranche object */ function safeTranche() external pure returns (ITranche); /** * @notice The address of the safeslip of the CBB * @dev using ClonesWithImmutableArgs pattern here to save gas * @dev https://github.com/wighawag/clones-with-immutable-args * @return The address of the safeslip of the CBB */ function safeSlipAddress() external pure returns (address); /** * @notice The tranche ratio of the safeTranche * @dev using ClonesWithImmutableArgs pattern here to save gas * @dev https://github.com/wighawag/clones-with-immutable-args * @return The tranche ratio of the safeTranche of the CBB */ function safeRatio() external pure returns (uint256); /** * @notice The riskTranche of the CBB * @dev using ClonesWithImmutableArgs pattern here to save gas * @dev https://github.com/wighawag/clones-with-immutable-args * @return The riskTranche tranche object */ function riskTranche() external pure returns (ITranche); /** * @notice The address of the riskSlip of the CBB * @dev using ClonesWithImmutableArgs pattern here to save gas * @dev https://github.com/wighawag/clones-with-immutable-args * @return The address of the riskSlip of the CBB */ function riskSlipAddress() external pure returns (address); /** * @notice The tranche ratio of the riskTranche * @dev using ClonesWithImmutableArgs pattern here to save gas * @dev https://github.com/wighawag/clones-with-immutable-args * @return The tranche ratio of the riskTranche of the CBB */ function riskRatio() external pure returns (uint256); /** * @notice The price granularity on the CBB * @dev using ClonesWithImmutableArgs pattern here to save gas * @dev https://github.com/wighawag/clones-with-immutable-args * @return The price granularity on the CBB */ function priceGranularity() external pure returns (uint256); /** * @notice The decimals of tranche-tokens * @dev using ClonesWithImmutableArgs pattern here to save gas * @dev https://github.com/wighawag/clones-with-immutable-args * @return The decimals of tranche-tokens */ function trancheDecimals() external pure returns (uint256); /** * @notice The decimals of stable-tokens * @dev using ClonesWithImmutableArgs pattern here to save gas * @dev https://github.com/wighawag/clones-with-immutable-args * @return The decimals of stable-tokens */ function stableDecimals() external pure returns (uint256); }
{ "remappings": [ "@buttonwood-protocol/button-wrappers/=lib/button-wrappers/", "@buttonwood-protocol/tranche/=lib/tranche/", "@openzeppelin/contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/", "@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/", "@uniswap/lib/=lib/solidity-lib/", "button-wrappers/=lib/button-wrappers/contracts/", "clones-with-immutable-args/=lib/clones-with-immutable-args/src/", "ds-test/=lib/clones-with-immutable-args/lib/ds-test/src/", "forge-std/=lib/forge-std/src/", "openzeppelin-contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/", "openzeppelin-contracts/=lib/openzeppelin-contracts/", "solidity-lib/=lib/solidity-lib/contracts/", "solmate/=lib/solmate/src/", "tranche/=lib/tranche/contracts/" ], "optimizer": { "enabled": true, "runs": 200 }, "metadata": { "bytecodeHash": "ipfs" }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "evmVersion": "london", "libraries": {} }
[{"inputs":[{"internalType":"uint256","name":"expectedAmount","type":"uint256"},{"internalType":"uint256","name":"minAmount","type":"uint256"}],"name":"SlippageExceeded","type":"error"},{"inputs":[{"internalType":"contract IStagingBox","name":"_stagingBox","type":"address"},{"internalType":"uint256","name":"_amountRaw","type":"uint256"},{"internalType":"uint256","name":"_minBorrowSlips","type":"uint256"}],"name":"multiWrapTrancheBorrow","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IStagingBox","name":"_stagingBox","type":"address"},{"internalType":"uint256","name":"_lendSlipAmount","type":"uint256"}],"name":"redeemLendSlipsForStables","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IStagingBox","name":"_stagingBox","type":"address"},{"internalType":"uint256","name":"_lendSlipAmount","type":"uint256"}],"name":"redeemLendSlipsForTranchesAndUnwrap","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IStagingBox","name":"_stagingBox","type":"address"},{"internalType":"uint256","name":"_riskSlipAmount","type":"uint256"}],"name":"redeemRiskSlipsForTranchesAndUnwrap","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IStagingBox","name":"_stagingBox","type":"address"},{"internalType":"uint256","name":"_safeSlipAmount","type":"uint256"}],"name":"redeemSafeSlipsForTranchesAndUnwrap","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IStagingBox","name":"_stagingBox","type":"address"},{"internalType":"uint256","name":"_stableAmount","type":"uint256"},{"internalType":"uint256","name":"_stableFees","type":"uint256"},{"internalType":"uint256","name":"_riskSlipAmount","type":"uint256"}],"name":"repayAndUnwrapMature","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IStagingBox","name":"_stagingBox","type":"address"},{"internalType":"uint256","name":"_stableAmount","type":"uint256"},{"internalType":"uint256","name":"_stableFees","type":"uint256"},{"internalType":"uint256","name":"_riskSlipAmount","type":"uint256"}],"name":"repayAndUnwrapSimple","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IStagingBox","name":"_stagingBox","type":"address"},{"internalType":"uint256","name":"_stableAmount","type":"uint256"},{"internalType":"uint256","name":"_stableFees","type":"uint256"},{"internalType":"uint256","name":"_riskSlipAmount","type":"uint256"}],"name":"repayMaxAndUnwrapSimple","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IStagingBox","name":"_stagingBox","type":"address"},{"internalType":"uint256","name":"_borrowSlipAmount","type":"uint256"}],"name":"simpleWithdrawBorrowUnwrap","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IStagingBox","name":"_stagingBox","type":"address"},{"internalType":"uint256","name":"_amountRaw","type":"uint256"},{"internalType":"uint256","name":"_minBorrowSlips","type":"uint256"}],"name":"simpleWrapTrancheBorrow","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
608060405234801561001057600080fd5b50613dbf806100206000396000f3fe608060405234801561001057600080fd5b506004361061009e5760003560e01c8063da0d330011610066578063da0d330014610104578063e5fdb09714610117578063ef182d6f1461012a578063eff839e91461013d578063f2e391551461015057600080fd5b806308b38060146100a357806344ad712a146100b8578063520d6520146100cb57806373120dfb146100de578063aca476e6146100f1575b600080fd5b6100b66100b1366004613a99565b610163565b005b6100b66100c6366004613ac5565b61044c565b6100b66100d9366004613a99565b610911565b6100b66100ec366004613a99565b610c6f565b6100b66100ff366004613b00565b610e7d565b6100b6610112366004613ac5565b6110eb565b6100b6610125366004613a99565b61178b565b6100b6610138366004613b00565b61187a565b6100b661014b366004613a99565b6122fb565b6100b661015e366004613ac5565b6126a8565b816001600160a01b0316633f8c59ee6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156101a1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101c59190613b35565b6001600160a01b03166323b872dd3330846040518463ffffffff1660e01b81526004016101f493929190613b52565b6020604051808303816000875af1158015610213573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102379190613b76565b5080826001600160a01b0316633f8c59ee6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610277573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061029b9190613b35565b6001600160a01b031663dd62ed3e30856040518363ffffffff1660e01b81526004016102c8929190613b98565b602060405180830381865afa1580156102e5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103099190613bb2565b10156103e557816001600160a01b0316633f8c59ee6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561034d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103719190613b35565b6001600160a01b031663095ea7b3836000196040518363ffffffff1660e01b81526004016103a0929190613bcb565b6020604051808303816000875af11580156103bf573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103e39190613b76565b505b60405163fa9bc04960e01b8152600481018290526001600160a01b0383169063fa9bc04990602401600060405180830381600087803b15801561042757600080fd5b505af115801561043b573d6000803e3d6000fd5b5050505061044882612a89565b5050565b600061045785612f73565b50505090506104d2816001600160a01b031663a9d75b2b6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561049d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104c19190613b35565b33306104cd8789613bfa565b613120565b806001600160a01b0316636fce86ec6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610510573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105349190613b35565b6001600160a01b03166323b872dd3330856040518463ffffffff1660e01b815260040161056393929190613b52565b6020604051808303816000875af1158015610582573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105a69190613b76565b506105b18385613bfa565b816001600160a01b031663a9d75b2b6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156105ef573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106139190613b35565b6001600160a01b031663dd62ed3e30846040518363ffffffff1660e01b8152600401610640929190613b98565b602060405180830381865afa15801561065d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106819190613bb2565b101561070957610709816001600160a01b031663a9d75b2b6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156106c8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106ec9190613b35565b82856106fa88600019613c12565b6107049190613c12565b613252565b604051631b8fec7360e11b8152600481018590526001600160a01b0382169063371fd8e690602401600060405180830381600087803b15801561074b57600080fd5b505af115801561075f573d6000803e3d6000fd5b5050505061076c85612a89565b806001600160a01b0316636fce86ec6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156107aa573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107ce9190613b35565b6001600160a01b031663a9059cbb33876001600160a01b031663952cd3436040518163ffffffff1660e01b8152600401602060405180830381865afa15801561081b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061083f9190613b35565b6040516370a0823160e01b81523060048201526001600160a01b0391909116906370a0823190602401602060405180830381865afa158015610885573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108a99190613bb2565b6040518363ffffffff1660e01b81526004016108c6929190613bcb565b6020604051808303816000875af11580156108e5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109099190613b76565b505050505050565b600080600061091f85612f73565b50925092509250826001600160a01b0316636fce86ec6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610964573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109889190613b35565b6001600160a01b03166323b872dd3330876040518463ffffffff1660e01b81526004016109b793929190613b52565b6020604051808303816000875af11580156109d6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109fa9190613b76565b5060405163f4bb631760e01b8152600481018590526001600160a01b0384169063f4bb631790602401600060405180830381600087803b158015610a3d57600080fd5b505af1158015610a51573d6000803e3d6000fd5b505050506000836001600160a01b0316633d13f81a6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610a95573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ab99190613b35565b6040516370a0823160e01b81523060048201526001600160a01b0391909116906370a0823190602401602060405180830381865afa158015610aff573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b239190613bb2565b9050826001600160a01b03166333d20e34856001600160a01b0316633d13f81a6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610b72573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b969190613b35565b836040518363ffffffff1660e01b8152600401610bb4929190613bcb565b600060405180830381600087803b158015610bce57600080fd5b505af1158015610be2573d6000803e3d6000fd5b50505050816001600160a01b031663ca9add8f610bfc3390565b6040516001600160e01b031960e084901b1681526001600160a01b0390911660048201526024016020604051808303816000875af1158015610c42573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c669190613bb2565b50505050505050565b816001600160a01b031663b57f808a6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610cad573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610cd19190613b35565b6001600160a01b03166323b872dd3330846040518463ffffffff1660e01b8152600401610d0093929190613b52565b6020604051808303816000875af1158015610d1f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d439190613b76565b506040516309ef29d560e41b8152600481018290526001600160a01b03831690639ef29d5090602401600060405180830381600087803b158015610d8657600080fd5b505af1158015610d9a573d6000803e3d6000fd5b505050506000826001600160a01b0316632bad788d6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610dde573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e029190613b35565b6040516370a0823160e01b81523060048201526001600160a01b0391909116906370a0823190602401602060405180830381865afa158015610e48573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e6c9190613bb2565b9050610e78838261332c565b505050565b610e8883838361187a565b600080610e9485612f73565b5050915091506000816001600160a01b03166359eb82246040518163ffffffff1660e01b8152600401602060405180830381865afa158015610eda573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610efe9190613bb2565b90506000836001600160a01b031663d0ab79fc6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610f40573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f649190613bb2565b905060005b828110156110e157818114158015610f8b5750610f87600184613c12565b8114155b156110d9576040516313612cb160e11b8152600481018290526000906001600160a01b038616906326c25962906024016040805180830381865afa158015610fd7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ffb9190613c29565b5090506001600160a01b03811663a9059cbb336040516370a0823160e01b81523060048201526001600160a01b038516906370a0823190602401602060405180830381865afa158015611052573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110769190613bb2565b6040518363ffffffff1660e01b8152600401611093929190613bcb565b6020604051808303816000875af11580156110b2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110d69190613b76565b50505b600101610f69565b5050505050505050565b60008060006110f987612f73565b50925092509250611171836001600160a01b031663a9d75b2b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611141573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111659190613b35565b33306104cd898b613bfa565b826001600160a01b0316636fce86ec6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156111af573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111d39190613b35565b6001600160a01b03166323b872dd3330876040518463ffffffff1660e01b815260040161120293929190613b52565b6020604051808303816000875af1158015611221573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112459190613b76565b506112508587613bfa565b836001600160a01b031663a9d75b2b6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561128e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112b29190613b35565b6001600160a01b031663dd62ed3e30866040518363ffffffff1660e01b81526004016112df929190613b98565b602060405180830381865afa1580156112fc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113209190613bb2565b101561139957611399836001600160a01b031663a9d75b2b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611367573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061138b9190613b35565b84876106fa8a600019613c12565b604051631b8fec7360e11b8152600481018790526001600160a01b0384169063371fd8e690602401600060405180830381600087803b1580156113db57600080fd5b505af11580156113ef573d6000803e3d6000fd5b50505050816001600160a01b03166333d20e34846001600160a01b0316634f95d4a66040518163ffffffff1660e01b8152600401602060405180830381865afa158015611440573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114649190613b35565b856001600160a01b0316634f95d4a66040518163ffffffff1660e01b8152600401602060405180830381865afa1580156114a2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114c69190613b35565b6040516370a0823160e01b81523060048201526001600160a01b0391909116906370a0823190602401602060405180830381865afa15801561150c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115309190613bb2565b6040518363ffffffff1660e01b815260040161154d929190613bcb565b600060405180830381600087803b15801561156757600080fd5b505af115801561157b573d6000803e3d6000fd5b50505050816001600160a01b03166333d20e34846001600160a01b0316633d13f81a6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156115cc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115f09190613b35565b856001600160a01b0316633d13f81a6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561162e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116529190613b35565b6040516370a0823160e01b81523060048201526001600160a01b0391909116906370a0823190602401602060405180830381865afa158015611698573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116bc9190613bb2565b6040518363ffffffff1660e01b81526004016116d9929190613bcb565b600060405180830381600087803b1580156116f357600080fd5b505af1158015611707573d6000803e3d6000fd5b50505050806001600160a01b031663ca9add8f6117213390565b6040516001600160e01b031960e084901b1681526001600160a01b0390911660048201526024016020604051808303816000875af1158015611767573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110e19190613bb2565b600061179683612f73565b5050509050806001600160a01b031663197daa3c6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156117d9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117fd9190613b35565b6001600160a01b03166323b872dd3330856040518463ffffffff1660e01b815260040161182c93929190613b52565b6020604051808303816000875af115801561184b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061186f9190613b76565b50610e78838361332c565b60008060008061188987612f73565b93509350935093506118a38161189c3390565b3089613120565b604051636eb1769f60e11b815286906001600160a01b0383169063dd62ed3e906118d39030908790600401613b98565b602060405180830381865afa1580156118f0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119149190613bb2565b101561198f5760405163095ea7b360e01b81526001600160a01b0382169063095ea7b39061194a90859060001990600401613bcb565b6020604051808303816000875af1158015611969573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061198d9190613b76565b505b60405163b6b55f2560e01b8152600481018790526000906001600160a01b0384169063b6b55f25906024016020604051808303816000875af11580156119d9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119fd9190613bb2565b60405163095ea7b360e01b81529091506001600160a01b0384169063095ea7b390611a3090879060001990600401613bcb565b6020604051808303816000875af1158015611a4f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a739190613b76565b5060405163b6b55f2560e01b8152600481018290526001600160a01b0385169063b6b55f2590602401600060405180830381600087803b158015611ab657600080fd5b505af1158015611aca573d6000803e3d6000fd5b505050506000886001600160a01b0316633d13f81a6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611b0e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b329190613b35565b6040516370a0823160e01b81523060048201526001600160a01b0391909116906370a0823190602401602060405180830381865afa158015611b78573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b9c9190613bb2565b90506000896001600160a01b0316634f95d4a66040518163ffffffff1660e01b8152600401602060405180830381865afa158015611bde573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c029190613b35565b6040516370a0823160e01b81523060048201526001600160a01b0391909116906370a0823190602401602060405180830381865afa158015611c48573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c6c9190613bb2565b9050808a6001600160a01b0316634f95d4a66040518163ffffffff1660e01b8152600401602060405180830381865afa158015611cad573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611cd19190613b35565b6001600160a01b031663dd62ed3e308d6040518363ffffffff1660e01b8152600401611cfe929190613b98565b602060405180830381865afa158015611d1b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d3f9190613bb2565b1015611e1b57896001600160a01b0316634f95d4a66040518163ffffffff1660e01b8152600401602060405180830381865afa158015611d83573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611da79190613b35565b6001600160a01b031663095ea7b38b6000196040518363ffffffff1660e01b8152600401611dd6929190613bcb565b6020604051808303816000875af1158015611df5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e199190613b76565b505b818a6001600160a01b0316633d13f81a6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611e5a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e7e9190613b35565b6001600160a01b031663dd62ed3e308d6040518363ffffffff1660e01b8152600401611eab929190613b98565b602060405180830381865afa158015611ec8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611eec9190613bb2565b1015611fc857896001600160a01b0316633d13f81a6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611f30573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f549190613b35565b6001600160a01b031663095ea7b38b6000196040518363ffffffff1660e01b8152600401611f83929190613bcb565b6020604051808303816000875af1158015611fa2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611fc69190613b76565b505b60008a6001600160a01b031663a1eb27ff6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612008573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061202c9190613bb2565b8b6001600160a01b031663edea9d6e6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561206a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061208e9190613bb2565b8c6001600160a01b0316632104d3fa6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156120cc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120f09190613bb2565b8d6001600160a01b0316631d0806ae6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561212e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121529190613bb2565b612233868d6001600160a01b03166351fd7d926040518163ffffffff1660e01b8152600401602060405180830381865afa158015612194573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121b89190613bb2565b8e6001600160a01b031663591269266040518163ffffffff1660e01b8152600401602060405180830381865afa1580156121f6573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061221a9190613bb2565b612224908b613c57565b61222e9190613c8c565b6136db565b61223d9190613c57565b6122479190613c57565b6122519190613c8c565b61225b9190613c8c565b604051631ecbac1360e11b81529091506001600160a01b038c1690633d9758269061228c9033908590600401613bcb565b600060405180830381600087803b1580156122a657600080fd5b505af11580156122ba573d6000803e3d6000fd5b50505050888110156122ee576040516371c4efed60e01b815260048101829052602481018a90526044015b60405180910390fd5b5050505050505050505050565b600061230683612f73565b5050509050826001600160a01b031663b57f808a6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612349573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061236d9190613b35565b6001600160a01b03166323b872dd3330856040518463ffffffff1660e01b815260040161239c93929190613b52565b6020604051808303816000875af11580156123bb573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123df9190613b76565b506040516309ef29d560e41b8152600481018390526001600160a01b03841690639ef29d5090602401600060405180830381600087803b15801561242257600080fd5b505af1158015612436573d6000803e3d6000fd5b505050506000836001600160a01b0316632bad788d6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561247a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061249e9190613b35565b6040516370a0823160e01b81523060048201526001600160a01b0391909116906370a0823190602401602060405180830381865afa1580156124e4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125089190613bb2565b604051636aab8f8160e11b8152600481018290529091506001600160a01b0383169063d5571f0290602401600060405180830381600087803b15801561254d57600080fd5b505af1158015612561573d6000803e3d6000fd5b505050506000826001600160a01b031663a9d75b2b6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156125a5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125c99190613b35565b6040516370a0823160e01b81523060048201526001600160a01b0391909116906370a0823190602401602060405180830381865afa15801561260f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126339190613bb2565b90506126a1836001600160a01b031663a9d75b2b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612676573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061269a9190613b35565b33836136f3565b5050505050565b60006126b385612f73565b50505090506126f9816001600160a01b031663a9d75b2b6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561049d573d6000803e3d6000fd5b806001600160a01b0316636fce86ec6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612737573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061275b9190613b35565b6001600160a01b03166323b872dd3330856040518463ffffffff1660e01b815260040161278a93929190613b52565b6020604051808303816000875af11580156127a9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127cd9190613b76565b506127d88385613bfa565b816001600160a01b031663a9d75b2b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612816573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061283a9190613b35565b6001600160a01b031663dd62ed3e30846040518363ffffffff1660e01b8152600401612867929190613b98565b602060405180830381865afa158015612884573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128a89190613bb2565b10156128ef576128ef816001600160a01b031663a9d75b2b6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156106c8573d6000803e3d6000fd5b60405163734291f560e01b8152600481018390526001600160a01b0382169063734291f590602401600060405180830381600087803b15801561293157600080fd5b505af1158015612945573d6000803e3d6000fd5b5050505061295285612a89565b6126a1816001600160a01b031663a9d75b2b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612993573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129b79190613b35565b33836001600160a01b031663a9d75b2b6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156129f6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a1a9190613b35565b6040516370a0823160e01b81523060048201526001600160a01b0391909116906370a0823190602401602060405180830381865afa158015612a60573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a849190613bb2565b6136f3565b6000806000612a9784612f73565b509250925092506000836001600160a01b031663591269266040518163ffffffff1660e01b8152600401602060405180830381865afa158015612ade573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b029190613bb2565b90506000846001600160a01b03166351fd7d926040518163ffffffff1660e01b8152600401602060405180830381865afa158015612b44573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b689190613bb2565b6040805160028082526060820183529293506000929091602083019080368337019050509050856001600160a01b0316634f95d4a66040518163ffffffff1660e01b8152600401602060405180830381865afa158015612bcc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612bf09190613b35565b6040516370a0823160e01b81523060048201526001600160a01b0391909116906370a0823190602401602060405180830381865afa158015612c36573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c5a9190613bb2565b81600081518110612c6d57612c6d613ca0565b602002602001018181525050856001600160a01b0316633d13f81a6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612cb7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612cdb9190613b35565b6040516370a0823160e01b81523060048201526001600160a01b0391909116906370a0823190602401602060405180830381865afa158015612d21573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d459190613bb2565b81600181518110612d5857612d58613ca0565b6020026020010181815250508281600181518110612d7857612d78613ca0565b6020026020010151612d8a9190613c57565b8282600081518110612d9e57612d9e613ca0565b6020026020010151612db09190613c57565b1015612e0b57828282600081518110612dcb57612dcb613ca0565b6020026020010151612ddd9190613c57565b612de79190613c8c565b81600181518110612dfa57612dfa613ca0565b602002602001018181525050612e5c565b818382600181518110612e2057612e20613ca0565b6020026020010151612e329190613c57565b612e3c9190613c8c565b81600081518110612e4f57612e4f613ca0565b6020026020010181815250505b8281600081518110612e7057612e70613ca0565b6020026020010151612e829190613cb6565b81600081518110612e9557612e95613ca0565b60200260200101818151612ea99190613c12565b9052508051829082906001908110612ec357612ec3613ca0565b6020026020010151612ed59190613cb6565b81600181518110612ee857612ee8613ca0565b60200260200101818151612efc9190613c12565b905250604051637cd7d93560e11b81526001600160a01b0386169063f9afb26a90612f2b908490600401613cca565b600060405180830381600087803b158015612f4557600080fd5b505af1158015612f59573d6000803e3d6000fd5b50505050836001600160a01b031663ca9add8f6117213390565b6000806000806000856001600160a01b031663c34b2a356040518163ffffffff1660e01b8152600401602060405180830381865afa158015612fb9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612fdd9190613b35565b90506000816001600160a01b03166364c9ec6f6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561301f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906130439190613b35565b90506000816001600160a01b031663b2016bd46040518163ffffffff1660e01b8152600401602060405180830381865afa158015613085573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906130a99190613b35565b90506000816001600160a01b0316636f307dc36040518163ffffffff1660e01b8152600401602060405180830381865afa1580156130eb573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061310f9190613b35565b939992985090965091945092505050565b600080856001600160a01b03166323b872dd86868660405160240161314793929190613b52565b6040516020818303038152906040529060e01b6020820180516001600160e01b0383818316178352505050506040516131809190613d3a565b6000604051808303816000865af19150503d80600081146131bd576040519150601f19603f3d011682016040523d82523d6000602084013e6131c2565b606091505b50915091508180156131ec5750805115806131ec5750808060200190518101906131ec9190613b76565b6109095760405162461bcd60e51b815260206004820152603160248201527f5472616e7366657248656c7065723a3a7472616e7366657246726f6d3a207472604482015270185b9cd9995c919c9bdb4819985a5b1959607a1b60648201526084016122e5565b600081846001600160a01b031663dd62ed3e30866040518363ffffffff1660e01b8152600401613283929190613b98565b602060405180830381865afa1580156132a0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906132c49190613bb2565b6132ce9190613bfa565b90506133268463095ea7b360e01b85846040516024016132ef929190613bcb565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b03199093169290921790915261381f565b50505050565b600080600061333a85612f73565b5060405163ec95efe360e01b81526004810188905292955090935091506001600160a01b0384169063ec95efe390602401600060405180830381600087803b15801561338557600080fd5b505af1158015613399573d6000803e3d6000fd5b505050506000836001600160a01b0316634f95d4a66040518163ffffffff1660e01b8152600401602060405180830381865afa1580156133dd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906134019190613b35565b6040516370a0823160e01b81523060048201526001600160a01b0391909116906370a0823190602401602060405180830381865afa158015613447573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061346b9190613bb2565b9050826001600160a01b03166333d20e34856001600160a01b0316634f95d4a66040518163ffffffff1660e01b8152600401602060405180830381865afa1580156134ba573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906134de9190613b35565b836040518363ffffffff1660e01b81526004016134fc929190613bcb565b600060405180830381600087803b15801561351657600080fd5b505af115801561352a573d6000803e3d6000fd5b505050506000846001600160a01b0316633d13f81a6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561356e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906135929190613b35565b6040516370a0823160e01b81523060048201526001600160a01b0391909116906370a0823190602401602060405180830381865afa1580156135d8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906135fc9190613bb2565b905080156136c657836001600160a01b03166333d20e34866001600160a01b0316633d13f81a6040518163ffffffff1660e01b8152600401602060405180830381865afa158015613651573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906136759190613b35565b836040518363ffffffff1660e01b8152600401613693929190613bcb565b600060405180830381600087803b1580156136ad57600080fd5b505af11580156136c1573d6000803e3d6000fd5b505050505b6001600160a01b03831663ca9add8f33611721565b60008183106136ea57816136ec565b825b9392505050565b600080846001600160a01b031663a9059cbb8585604051602401613718929190613bcb565b6040516020818303038152906040529060e01b6020820180516001600160e01b0383818316178352505050506040516137519190613d3a565b6000604051808303816000865af19150503d806000811461378e576040519150601f19603f3d011682016040523d82523d6000602084013e613793565b606091505b50915091508180156137bd5750805115806137bd5750808060200190518101906137bd9190613b76565b6126a15760405162461bcd60e51b815260206004820152602d60248201527f5472616e7366657248656c7065723a3a736166655472616e736665723a20747260448201526c185b9cd9995c8819985a5b1959609a1b60648201526084016122e5565b6000613874826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166138f19092919063ffffffff16565b805190915015610e7857808060200190518101906138929190613b76565b610e785760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b60648201526084016122e5565b60606139008484600085613908565b949350505050565b6060824710156139695760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b60648201526084016122e5565b600080866001600160a01b031685876040516139859190613d3a565b60006040518083038185875af1925050503d80600081146139c2576040519150601f19603f3d011682016040523d82523d6000602084013e6139c7565b606091505b50915091506139d8878383876139e3565b979650505050505050565b60608315613a52578251600003613a4b576001600160a01b0385163b613a4b5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016122e5565b5081613900565b6139008383815115613a675781518083602001fd5b8060405162461bcd60e51b81526004016122e59190613d56565b6001600160a01b0381168114613a9657600080fd5b50565b60008060408385031215613aac57600080fd5b8235613ab781613a81565b946020939093013593505050565b60008060008060808587031215613adb57600080fd5b8435613ae681613a81565b966020860135965060408601359560600135945092505050565b600080600060608486031215613b1557600080fd5b8335613b2081613a81565b95602085013595506040909401359392505050565b600060208284031215613b4757600080fd5b81516136ec81613a81565b6001600160a01b039384168152919092166020820152604081019190915260600190565b600060208284031215613b8857600080fd5b815180151581146136ec57600080fd5b6001600160a01b0392831681529116602082015260400190565b600060208284031215613bc457600080fd5b5051919050565b6001600160a01b03929092168252602082015260400190565b634e487b7160e01b600052601160045260246000fd5b60008219821115613c0d57613c0d613be4565b500190565b600082821015613c2457613c24613be4565b500390565b60008060408385031215613c3c57600080fd5b8251613c4781613a81565b6020939093015192949293505050565b6000816000190483118215151615613c7157613c71613be4565b500290565b634e487b7160e01b600052601260045260246000fd5b600082613c9b57613c9b613c76565b500490565b634e487b7160e01b600052603260045260246000fd5b600082613cc557613cc5613c76565b500690565b6020808252825182820181905260009190848201906040850190845b81811015613d0257835183529284019291840191600101613ce6565b50909695505050505050565b60005b83811015613d29578181015183820152602001613d11565b838111156133265750506000910152565b60008251613d4c818460208701613d0e565b9190910192915050565b6020815260008251806020840152613d75816040850160208701613d0e565b601f01601f1916919091016040019291505056fea264697066735822122044e816acc53acb41011cb3619d537faf5dac6e24dce4c0ab43e9f2a99d959a7f64736f6c634300080d0033
Deployed Bytecode
0x608060405234801561001057600080fd5b506004361061009e5760003560e01c8063da0d330011610066578063da0d330014610104578063e5fdb09714610117578063ef182d6f1461012a578063eff839e91461013d578063f2e391551461015057600080fd5b806308b38060146100a357806344ad712a146100b8578063520d6520146100cb57806373120dfb146100de578063aca476e6146100f1575b600080fd5b6100b66100b1366004613a99565b610163565b005b6100b66100c6366004613ac5565b61044c565b6100b66100d9366004613a99565b610911565b6100b66100ec366004613a99565b610c6f565b6100b66100ff366004613b00565b610e7d565b6100b6610112366004613ac5565b6110eb565b6100b6610125366004613a99565b61178b565b6100b6610138366004613b00565b61187a565b6100b661014b366004613a99565b6122fb565b6100b661015e366004613ac5565b6126a8565b816001600160a01b0316633f8c59ee6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156101a1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101c59190613b35565b6001600160a01b03166323b872dd3330846040518463ffffffff1660e01b81526004016101f493929190613b52565b6020604051808303816000875af1158015610213573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102379190613b76565b5080826001600160a01b0316633f8c59ee6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610277573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061029b9190613b35565b6001600160a01b031663dd62ed3e30856040518363ffffffff1660e01b81526004016102c8929190613b98565b602060405180830381865afa1580156102e5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103099190613bb2565b10156103e557816001600160a01b0316633f8c59ee6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561034d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103719190613b35565b6001600160a01b031663095ea7b3836000196040518363ffffffff1660e01b81526004016103a0929190613bcb565b6020604051808303816000875af11580156103bf573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103e39190613b76565b505b60405163fa9bc04960e01b8152600481018290526001600160a01b0383169063fa9bc04990602401600060405180830381600087803b15801561042757600080fd5b505af115801561043b573d6000803e3d6000fd5b5050505061044882612a89565b5050565b600061045785612f73565b50505090506104d2816001600160a01b031663a9d75b2b6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561049d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104c19190613b35565b33306104cd8789613bfa565b613120565b806001600160a01b0316636fce86ec6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610510573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105349190613b35565b6001600160a01b03166323b872dd3330856040518463ffffffff1660e01b815260040161056393929190613b52565b6020604051808303816000875af1158015610582573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105a69190613b76565b506105b18385613bfa565b816001600160a01b031663a9d75b2b6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156105ef573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106139190613b35565b6001600160a01b031663dd62ed3e30846040518363ffffffff1660e01b8152600401610640929190613b98565b602060405180830381865afa15801561065d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106819190613bb2565b101561070957610709816001600160a01b031663a9d75b2b6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156106c8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106ec9190613b35565b82856106fa88600019613c12565b6107049190613c12565b613252565b604051631b8fec7360e11b8152600481018590526001600160a01b0382169063371fd8e690602401600060405180830381600087803b15801561074b57600080fd5b505af115801561075f573d6000803e3d6000fd5b5050505061076c85612a89565b806001600160a01b0316636fce86ec6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156107aa573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107ce9190613b35565b6001600160a01b031663a9059cbb33876001600160a01b031663952cd3436040518163ffffffff1660e01b8152600401602060405180830381865afa15801561081b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061083f9190613b35565b6040516370a0823160e01b81523060048201526001600160a01b0391909116906370a0823190602401602060405180830381865afa158015610885573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108a99190613bb2565b6040518363ffffffff1660e01b81526004016108c6929190613bcb565b6020604051808303816000875af11580156108e5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109099190613b76565b505050505050565b600080600061091f85612f73565b50925092509250826001600160a01b0316636fce86ec6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610964573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109889190613b35565b6001600160a01b03166323b872dd3330876040518463ffffffff1660e01b81526004016109b793929190613b52565b6020604051808303816000875af11580156109d6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109fa9190613b76565b5060405163f4bb631760e01b8152600481018590526001600160a01b0384169063f4bb631790602401600060405180830381600087803b158015610a3d57600080fd5b505af1158015610a51573d6000803e3d6000fd5b505050506000836001600160a01b0316633d13f81a6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610a95573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ab99190613b35565b6040516370a0823160e01b81523060048201526001600160a01b0391909116906370a0823190602401602060405180830381865afa158015610aff573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b239190613bb2565b9050826001600160a01b03166333d20e34856001600160a01b0316633d13f81a6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610b72573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b969190613b35565b836040518363ffffffff1660e01b8152600401610bb4929190613bcb565b600060405180830381600087803b158015610bce57600080fd5b505af1158015610be2573d6000803e3d6000fd5b50505050816001600160a01b031663ca9add8f610bfc3390565b6040516001600160e01b031960e084901b1681526001600160a01b0390911660048201526024016020604051808303816000875af1158015610c42573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c669190613bb2565b50505050505050565b816001600160a01b031663b57f808a6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610cad573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610cd19190613b35565b6001600160a01b03166323b872dd3330846040518463ffffffff1660e01b8152600401610d0093929190613b52565b6020604051808303816000875af1158015610d1f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d439190613b76565b506040516309ef29d560e41b8152600481018290526001600160a01b03831690639ef29d5090602401600060405180830381600087803b158015610d8657600080fd5b505af1158015610d9a573d6000803e3d6000fd5b505050506000826001600160a01b0316632bad788d6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610dde573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e029190613b35565b6040516370a0823160e01b81523060048201526001600160a01b0391909116906370a0823190602401602060405180830381865afa158015610e48573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e6c9190613bb2565b9050610e78838261332c565b505050565b610e8883838361187a565b600080610e9485612f73565b5050915091506000816001600160a01b03166359eb82246040518163ffffffff1660e01b8152600401602060405180830381865afa158015610eda573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610efe9190613bb2565b90506000836001600160a01b031663d0ab79fc6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610f40573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f649190613bb2565b905060005b828110156110e157818114158015610f8b5750610f87600184613c12565b8114155b156110d9576040516313612cb160e11b8152600481018290526000906001600160a01b038616906326c25962906024016040805180830381865afa158015610fd7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ffb9190613c29565b5090506001600160a01b03811663a9059cbb336040516370a0823160e01b81523060048201526001600160a01b038516906370a0823190602401602060405180830381865afa158015611052573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110769190613bb2565b6040518363ffffffff1660e01b8152600401611093929190613bcb565b6020604051808303816000875af11580156110b2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110d69190613b76565b50505b600101610f69565b5050505050505050565b60008060006110f987612f73565b50925092509250611171836001600160a01b031663a9d75b2b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611141573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111659190613b35565b33306104cd898b613bfa565b826001600160a01b0316636fce86ec6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156111af573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111d39190613b35565b6001600160a01b03166323b872dd3330876040518463ffffffff1660e01b815260040161120293929190613b52565b6020604051808303816000875af1158015611221573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112459190613b76565b506112508587613bfa565b836001600160a01b031663a9d75b2b6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561128e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112b29190613b35565b6001600160a01b031663dd62ed3e30866040518363ffffffff1660e01b81526004016112df929190613b98565b602060405180830381865afa1580156112fc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113209190613bb2565b101561139957611399836001600160a01b031663a9d75b2b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611367573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061138b9190613b35565b84876106fa8a600019613c12565b604051631b8fec7360e11b8152600481018790526001600160a01b0384169063371fd8e690602401600060405180830381600087803b1580156113db57600080fd5b505af11580156113ef573d6000803e3d6000fd5b50505050816001600160a01b03166333d20e34846001600160a01b0316634f95d4a66040518163ffffffff1660e01b8152600401602060405180830381865afa158015611440573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114649190613b35565b856001600160a01b0316634f95d4a66040518163ffffffff1660e01b8152600401602060405180830381865afa1580156114a2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114c69190613b35565b6040516370a0823160e01b81523060048201526001600160a01b0391909116906370a0823190602401602060405180830381865afa15801561150c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115309190613bb2565b6040518363ffffffff1660e01b815260040161154d929190613bcb565b600060405180830381600087803b15801561156757600080fd5b505af115801561157b573d6000803e3d6000fd5b50505050816001600160a01b03166333d20e34846001600160a01b0316633d13f81a6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156115cc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115f09190613b35565b856001600160a01b0316633d13f81a6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561162e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116529190613b35565b6040516370a0823160e01b81523060048201526001600160a01b0391909116906370a0823190602401602060405180830381865afa158015611698573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116bc9190613bb2565b6040518363ffffffff1660e01b81526004016116d9929190613bcb565b600060405180830381600087803b1580156116f357600080fd5b505af1158015611707573d6000803e3d6000fd5b50505050806001600160a01b031663ca9add8f6117213390565b6040516001600160e01b031960e084901b1681526001600160a01b0390911660048201526024016020604051808303816000875af1158015611767573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110e19190613bb2565b600061179683612f73565b5050509050806001600160a01b031663197daa3c6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156117d9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117fd9190613b35565b6001600160a01b03166323b872dd3330856040518463ffffffff1660e01b815260040161182c93929190613b52565b6020604051808303816000875af115801561184b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061186f9190613b76565b50610e78838361332c565b60008060008061188987612f73565b93509350935093506118a38161189c3390565b3089613120565b604051636eb1769f60e11b815286906001600160a01b0383169063dd62ed3e906118d39030908790600401613b98565b602060405180830381865afa1580156118f0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119149190613bb2565b101561198f5760405163095ea7b360e01b81526001600160a01b0382169063095ea7b39061194a90859060001990600401613bcb565b6020604051808303816000875af1158015611969573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061198d9190613b76565b505b60405163b6b55f2560e01b8152600481018790526000906001600160a01b0384169063b6b55f25906024016020604051808303816000875af11580156119d9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119fd9190613bb2565b60405163095ea7b360e01b81529091506001600160a01b0384169063095ea7b390611a3090879060001990600401613bcb565b6020604051808303816000875af1158015611a4f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a739190613b76565b5060405163b6b55f2560e01b8152600481018290526001600160a01b0385169063b6b55f2590602401600060405180830381600087803b158015611ab657600080fd5b505af1158015611aca573d6000803e3d6000fd5b505050506000886001600160a01b0316633d13f81a6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611b0e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b329190613b35565b6040516370a0823160e01b81523060048201526001600160a01b0391909116906370a0823190602401602060405180830381865afa158015611b78573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b9c9190613bb2565b90506000896001600160a01b0316634f95d4a66040518163ffffffff1660e01b8152600401602060405180830381865afa158015611bde573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c029190613b35565b6040516370a0823160e01b81523060048201526001600160a01b0391909116906370a0823190602401602060405180830381865afa158015611c48573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c6c9190613bb2565b9050808a6001600160a01b0316634f95d4a66040518163ffffffff1660e01b8152600401602060405180830381865afa158015611cad573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611cd19190613b35565b6001600160a01b031663dd62ed3e308d6040518363ffffffff1660e01b8152600401611cfe929190613b98565b602060405180830381865afa158015611d1b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d3f9190613bb2565b1015611e1b57896001600160a01b0316634f95d4a66040518163ffffffff1660e01b8152600401602060405180830381865afa158015611d83573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611da79190613b35565b6001600160a01b031663095ea7b38b6000196040518363ffffffff1660e01b8152600401611dd6929190613bcb565b6020604051808303816000875af1158015611df5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e199190613b76565b505b818a6001600160a01b0316633d13f81a6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611e5a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e7e9190613b35565b6001600160a01b031663dd62ed3e308d6040518363ffffffff1660e01b8152600401611eab929190613b98565b602060405180830381865afa158015611ec8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611eec9190613bb2565b1015611fc857896001600160a01b0316633d13f81a6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611f30573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f549190613b35565b6001600160a01b031663095ea7b38b6000196040518363ffffffff1660e01b8152600401611f83929190613bcb565b6020604051808303816000875af1158015611fa2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611fc69190613b76565b505b60008a6001600160a01b031663a1eb27ff6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612008573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061202c9190613bb2565b8b6001600160a01b031663edea9d6e6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561206a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061208e9190613bb2565b8c6001600160a01b0316632104d3fa6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156120cc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120f09190613bb2565b8d6001600160a01b0316631d0806ae6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561212e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121529190613bb2565b612233868d6001600160a01b03166351fd7d926040518163ffffffff1660e01b8152600401602060405180830381865afa158015612194573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121b89190613bb2565b8e6001600160a01b031663591269266040518163ffffffff1660e01b8152600401602060405180830381865afa1580156121f6573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061221a9190613bb2565b612224908b613c57565b61222e9190613c8c565b6136db565b61223d9190613c57565b6122479190613c57565b6122519190613c8c565b61225b9190613c8c565b604051631ecbac1360e11b81529091506001600160a01b038c1690633d9758269061228c9033908590600401613bcb565b600060405180830381600087803b1580156122a657600080fd5b505af11580156122ba573d6000803e3d6000fd5b50505050888110156122ee576040516371c4efed60e01b815260048101829052602481018a90526044015b60405180910390fd5b5050505050505050505050565b600061230683612f73565b5050509050826001600160a01b031663b57f808a6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612349573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061236d9190613b35565b6001600160a01b03166323b872dd3330856040518463ffffffff1660e01b815260040161239c93929190613b52565b6020604051808303816000875af11580156123bb573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123df9190613b76565b506040516309ef29d560e41b8152600481018390526001600160a01b03841690639ef29d5090602401600060405180830381600087803b15801561242257600080fd5b505af1158015612436573d6000803e3d6000fd5b505050506000836001600160a01b0316632bad788d6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561247a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061249e9190613b35565b6040516370a0823160e01b81523060048201526001600160a01b0391909116906370a0823190602401602060405180830381865afa1580156124e4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125089190613bb2565b604051636aab8f8160e11b8152600481018290529091506001600160a01b0383169063d5571f0290602401600060405180830381600087803b15801561254d57600080fd5b505af1158015612561573d6000803e3d6000fd5b505050506000826001600160a01b031663a9d75b2b6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156125a5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125c99190613b35565b6040516370a0823160e01b81523060048201526001600160a01b0391909116906370a0823190602401602060405180830381865afa15801561260f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126339190613bb2565b90506126a1836001600160a01b031663a9d75b2b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612676573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061269a9190613b35565b33836136f3565b5050505050565b60006126b385612f73565b50505090506126f9816001600160a01b031663a9d75b2b6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561049d573d6000803e3d6000fd5b806001600160a01b0316636fce86ec6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612737573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061275b9190613b35565b6001600160a01b03166323b872dd3330856040518463ffffffff1660e01b815260040161278a93929190613b52565b6020604051808303816000875af11580156127a9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127cd9190613b76565b506127d88385613bfa565b816001600160a01b031663a9d75b2b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612816573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061283a9190613b35565b6001600160a01b031663dd62ed3e30846040518363ffffffff1660e01b8152600401612867929190613b98565b602060405180830381865afa158015612884573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128a89190613bb2565b10156128ef576128ef816001600160a01b031663a9d75b2b6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156106c8573d6000803e3d6000fd5b60405163734291f560e01b8152600481018390526001600160a01b0382169063734291f590602401600060405180830381600087803b15801561293157600080fd5b505af1158015612945573d6000803e3d6000fd5b5050505061295285612a89565b6126a1816001600160a01b031663a9d75b2b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612993573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129b79190613b35565b33836001600160a01b031663a9d75b2b6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156129f6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a1a9190613b35565b6040516370a0823160e01b81523060048201526001600160a01b0391909116906370a0823190602401602060405180830381865afa158015612a60573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a849190613bb2565b6136f3565b6000806000612a9784612f73565b509250925092506000836001600160a01b031663591269266040518163ffffffff1660e01b8152600401602060405180830381865afa158015612ade573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b029190613bb2565b90506000846001600160a01b03166351fd7d926040518163ffffffff1660e01b8152600401602060405180830381865afa158015612b44573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b689190613bb2565b6040805160028082526060820183529293506000929091602083019080368337019050509050856001600160a01b0316634f95d4a66040518163ffffffff1660e01b8152600401602060405180830381865afa158015612bcc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612bf09190613b35565b6040516370a0823160e01b81523060048201526001600160a01b0391909116906370a0823190602401602060405180830381865afa158015612c36573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c5a9190613bb2565b81600081518110612c6d57612c6d613ca0565b602002602001018181525050856001600160a01b0316633d13f81a6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612cb7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612cdb9190613b35565b6040516370a0823160e01b81523060048201526001600160a01b0391909116906370a0823190602401602060405180830381865afa158015612d21573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d459190613bb2565b81600181518110612d5857612d58613ca0565b6020026020010181815250508281600181518110612d7857612d78613ca0565b6020026020010151612d8a9190613c57565b8282600081518110612d9e57612d9e613ca0565b6020026020010151612db09190613c57565b1015612e0b57828282600081518110612dcb57612dcb613ca0565b6020026020010151612ddd9190613c57565b612de79190613c8c565b81600181518110612dfa57612dfa613ca0565b602002602001018181525050612e5c565b818382600181518110612e2057612e20613ca0565b6020026020010151612e329190613c57565b612e3c9190613c8c565b81600081518110612e4f57612e4f613ca0565b6020026020010181815250505b8281600081518110612e7057612e70613ca0565b6020026020010151612e829190613cb6565b81600081518110612e9557612e95613ca0565b60200260200101818151612ea99190613c12565b9052508051829082906001908110612ec357612ec3613ca0565b6020026020010151612ed59190613cb6565b81600181518110612ee857612ee8613ca0565b60200260200101818151612efc9190613c12565b905250604051637cd7d93560e11b81526001600160a01b0386169063f9afb26a90612f2b908490600401613cca565b600060405180830381600087803b158015612f4557600080fd5b505af1158015612f59573d6000803e3d6000fd5b50505050836001600160a01b031663ca9add8f6117213390565b6000806000806000856001600160a01b031663c34b2a356040518163ffffffff1660e01b8152600401602060405180830381865afa158015612fb9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612fdd9190613b35565b90506000816001600160a01b03166364c9ec6f6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561301f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906130439190613b35565b90506000816001600160a01b031663b2016bd46040518163ffffffff1660e01b8152600401602060405180830381865afa158015613085573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906130a99190613b35565b90506000816001600160a01b0316636f307dc36040518163ffffffff1660e01b8152600401602060405180830381865afa1580156130eb573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061310f9190613b35565b939992985090965091945092505050565b600080856001600160a01b03166323b872dd86868660405160240161314793929190613b52565b6040516020818303038152906040529060e01b6020820180516001600160e01b0383818316178352505050506040516131809190613d3a565b6000604051808303816000865af19150503d80600081146131bd576040519150601f19603f3d011682016040523d82523d6000602084013e6131c2565b606091505b50915091508180156131ec5750805115806131ec5750808060200190518101906131ec9190613b76565b6109095760405162461bcd60e51b815260206004820152603160248201527f5472616e7366657248656c7065723a3a7472616e7366657246726f6d3a207472604482015270185b9cd9995c919c9bdb4819985a5b1959607a1b60648201526084016122e5565b600081846001600160a01b031663dd62ed3e30866040518363ffffffff1660e01b8152600401613283929190613b98565b602060405180830381865afa1580156132a0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906132c49190613bb2565b6132ce9190613bfa565b90506133268463095ea7b360e01b85846040516024016132ef929190613bcb565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b03199093169290921790915261381f565b50505050565b600080600061333a85612f73565b5060405163ec95efe360e01b81526004810188905292955090935091506001600160a01b0384169063ec95efe390602401600060405180830381600087803b15801561338557600080fd5b505af1158015613399573d6000803e3d6000fd5b505050506000836001600160a01b0316634f95d4a66040518163ffffffff1660e01b8152600401602060405180830381865afa1580156133dd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906134019190613b35565b6040516370a0823160e01b81523060048201526001600160a01b0391909116906370a0823190602401602060405180830381865afa158015613447573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061346b9190613bb2565b9050826001600160a01b03166333d20e34856001600160a01b0316634f95d4a66040518163ffffffff1660e01b8152600401602060405180830381865afa1580156134ba573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906134de9190613b35565b836040518363ffffffff1660e01b81526004016134fc929190613bcb565b600060405180830381600087803b15801561351657600080fd5b505af115801561352a573d6000803e3d6000fd5b505050506000846001600160a01b0316633d13f81a6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561356e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906135929190613b35565b6040516370a0823160e01b81523060048201526001600160a01b0391909116906370a0823190602401602060405180830381865afa1580156135d8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906135fc9190613bb2565b905080156136c657836001600160a01b03166333d20e34866001600160a01b0316633d13f81a6040518163ffffffff1660e01b8152600401602060405180830381865afa158015613651573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906136759190613b35565b836040518363ffffffff1660e01b8152600401613693929190613bcb565b600060405180830381600087803b1580156136ad57600080fd5b505af11580156136c1573d6000803e3d6000fd5b505050505b6001600160a01b03831663ca9add8f33611721565b60008183106136ea57816136ec565b825b9392505050565b600080846001600160a01b031663a9059cbb8585604051602401613718929190613bcb565b6040516020818303038152906040529060e01b6020820180516001600160e01b0383818316178352505050506040516137519190613d3a565b6000604051808303816000865af19150503d806000811461378e576040519150601f19603f3d011682016040523d82523d6000602084013e613793565b606091505b50915091508180156137bd5750805115806137bd5750808060200190518101906137bd9190613b76565b6126a15760405162461bcd60e51b815260206004820152602d60248201527f5472616e7366657248656c7065723a3a736166655472616e736665723a20747260448201526c185b9cd9995c8819985a5b1959609a1b60648201526084016122e5565b6000613874826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166138f19092919063ffffffff16565b805190915015610e7857808060200190518101906138929190613b76565b610e785760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b60648201526084016122e5565b60606139008484600085613908565b949350505050565b6060824710156139695760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b60648201526084016122e5565b600080866001600160a01b031685876040516139859190613d3a565b60006040518083038185875af1925050503d80600081146139c2576040519150601f19603f3d011682016040523d82523d6000602084013e6139c7565b606091505b50915091506139d8878383876139e3565b979650505050505050565b60608315613a52578251600003613a4b576001600160a01b0385163b613a4b5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016122e5565b5081613900565b6139008383815115613a675781518083602001fd5b8060405162461bcd60e51b81526004016122e59190613d56565b6001600160a01b0381168114613a9657600080fd5b50565b60008060408385031215613aac57600080fd5b8235613ab781613a81565b946020939093013593505050565b60008060008060808587031215613adb57600080fd5b8435613ae681613a81565b966020860135965060408601359560600135945092505050565b600080600060608486031215613b1557600080fd5b8335613b2081613a81565b95602085013595506040909401359392505050565b600060208284031215613b4757600080fd5b81516136ec81613a81565b6001600160a01b039384168152919092166020820152604081019190915260600190565b600060208284031215613b8857600080fd5b815180151581146136ec57600080fd5b6001600160a01b0392831681529116602082015260400190565b600060208284031215613bc457600080fd5b5051919050565b6001600160a01b03929092168252602082015260400190565b634e487b7160e01b600052601160045260246000fd5b60008219821115613c0d57613c0d613be4565b500190565b600082821015613c2457613c24613be4565b500390565b60008060408385031215613c3c57600080fd5b8251613c4781613a81565b6020939093015192949293505050565b6000816000190483118215151615613c7157613c71613be4565b500290565b634e487b7160e01b600052601260045260246000fd5b600082613c9b57613c9b613c76565b500490565b634e487b7160e01b600052603260045260246000fd5b600082613cc557613cc5613c76565b500690565b6020808252825182820181905260009190848201906040850190845b81811015613d0257835183529284019291840191600101613ce6565b50909695505050505050565b60005b83811015613d29578181015183820152602001613d11565b838111156133265750506000910152565b60008251613d4c818460208701613d0e565b9190910192915050565b6020815260008251806020840152613d75816040850160208701613d0e565b601f01601f1916919091016040019291505056fea264697066735822122044e816acc53acb41011cb3619d537faf5dac6e24dce4c0ab43e9f2a99d959a7f64736f6c634300080d0033
Loading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.