Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
Latest 25 from a total of 35 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Withdraw Hourly ... | 17423750 | 599 days ago | IN | 0 ETH | 0.005469 | ||||
Withdraw Hourly ... | 17423744 | 599 days ago | IN | 0 ETH | 0.00464165 | ||||
Withdraw Hourly ... | 14892358 | 968 days ago | IN | 0 ETH | 0.01056015 | ||||
Buy Hourly Bond ... | 14889807 | 968 days ago | IN | 0 ETH | 0.01226532 | ||||
Withdraw Hourly ... | 14620502 | 1011 days ago | IN | 0 ETH | 0.00515815 | ||||
Buy Hourly Bond ... | 14616885 | 1012 days ago | IN | 0 ETH | 0.00899899 | ||||
Buy Hourly Bond ... | 14486784 | 1032 days ago | IN | 0 ETH | 0.00645993 | ||||
Buy Hourly Bond ... | 14354197 | 1053 days ago | IN | 0 ETH | 0.00844431 | ||||
Withdraw Hourly ... | 14349719 | 1053 days ago | IN | 0 ETH | 0.00425886 | ||||
Withdraw Hourly ... | 14131481 | 1087 days ago | IN | 0 ETH | 0.01137733 | ||||
Buy Hourly Bond ... | 14112000 | 1090 days ago | IN | 0 ETH | 0.01538167 | ||||
Withdraw Hourly ... | 13706196 | 1153 days ago | IN | 0 ETH | 0.01077411 | ||||
Buy Hourly Bond ... | 13497236 | 1186 days ago | IN | 0 ETH | 0.02523382 | ||||
Buy Hourly Bond ... | 13492278 | 1187 days ago | IN | 0 ETH | 0.00899364 | ||||
Withdraw Hourly ... | 13492078 | 1187 days ago | IN | 0 ETH | 0.0141771 | ||||
Buy Hourly Bond ... | 13461509 | 1192 days ago | IN | 0 ETH | 0.01454083 | ||||
Withdraw Hourly ... | 13454762 | 1193 days ago | IN | 0 ETH | 0.00642444 | ||||
Withdraw Hourly ... | 13454628 | 1193 days ago | IN | 0 ETH | 0.00701428 | ||||
Withdraw Hourly ... | 13454365 | 1193 days ago | IN | 0 ETH | 0.00813925 | ||||
Buy Hourly Bond ... | 13351887 | 1209 days ago | IN | 0 ETH | 0.00837734 | ||||
Withdraw Hourly ... | 13261665 | 1223 days ago | IN | 0 ETH | 0.00566724 | ||||
Withdraw Hourly ... | 13229807 | 1228 days ago | IN | 0 ETH | 0.005066 | ||||
Withdraw Hourly ... | 13229752 | 1228 days ago | IN | 0 ETH | 0.00394728 | ||||
Withdraw Hourly ... | 13222196 | 1229 days ago | IN | 0 ETH | 0.00485901 | ||||
Buy Hourly Bond ... | 13106509 | 1247 days ago | IN | 0 ETH | 0.01072071 |
Advanced mode: Intended for advanced users or developers and will display all Internal Transactions including zero value transfers. Name tag integration is not available in advanced view.
Latest 25 internal transactions (View All)
Advanced mode:
Parent Transaction Hash | Block |
From
|
To
|
||||
---|---|---|---|---|---|---|---|
17423750 | 599 days ago | 0 ETH | |||||
17423744 | 599 days ago | 0 ETH | |||||
15898446 | 813 days ago | 0 ETH | |||||
15898436 | 813 days ago | 0 ETH | |||||
15898436 | 813 days ago | 0 ETH | |||||
15898436 | 813 days ago | 0 ETH | |||||
15898431 | 813 days ago | 0 ETH | |||||
15898431 | 813 days ago | 0 ETH | |||||
15898431 | 813 days ago | 0 ETH | |||||
15898425 | 813 days ago | 0 ETH | |||||
15898425 | 813 days ago | 0 ETH | |||||
15898425 | 813 days ago | 0 ETH | |||||
14892358 | 968 days ago | 0 ETH | |||||
14889807 | 968 days ago | 0 ETH | |||||
14620502 | 1011 days ago | 0 ETH | |||||
14616885 | 1012 days ago | 0 ETH | |||||
14486784 | 1032 days ago | 0 ETH | |||||
14354197 | 1053 days ago | 0 ETH | |||||
14349719 | 1053 days ago | 0 ETH | |||||
14149882 | 1084 days ago | 0 ETH | |||||
14149882 | 1084 days ago | 0 ETH | |||||
14149882 | 1084 days ago | 0 ETH | |||||
14149819 | 1084 days ago | 0 ETH | |||||
14149819 | 1084 days ago | 0 ETH | |||||
14149819 | 1084 days ago | 0 ETH |
Loading...
Loading
Contract Source Code Verified (Exact Match)
Contract Name:
Lending
Compiler Version
v0.8.3+commit.8d00100c
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.0; import "./Fund.sol"; import "./HourlyBondSubscriptionLending.sol"; import "../libraries/IncentiveReporter.sol"; // TODO activate bonds for lending /// @title Manage lending for a variety of bond issuers contract Lending is RoleAware, HourlyBondSubscriptionLending { /// mapping issuers to tokens /// (in crossmargin, the issuers are tokens themselves) mapping(address => address) public issuerTokens; /// In case of shortfall, adjust debt mapping(address => uint256) public haircuts; /// map of available issuers mapping(address => bool) public activeIssuers; uint256 constant BORROW_RATE_UPDATE_WINDOW = 60 minutes; address public immutable MFI; constructor(address _MFI, address _roles) RoleAware(_roles) { MFI = _MFI; } /// Make a issuer available for protocol function activateIssuer(address issuer) external { activateIssuer(issuer, issuer); } /// Make issuer != token available for protocol (isol. margin) function activateIssuer(address issuer, address token) public onlyOwnerExecActivator { activeIssuers[issuer] = true; issuerTokens[issuer] = token; } /// Remove a issuer from trading availability function deactivateIssuer(address issuer) external onlyOwnerExecActivator { activeIssuers[issuer] = false; } /// Set lending cap function setLendingCap(address issuer, uint256 cap) external onlyOwnerExecActivator { lendingMeta[issuer].lendingCap = cap; } /// Set withdrawal window function setWithdrawalWindow(uint256 window) external onlyOwnerExec { withdrawalWindow = window; } function setNormalRatePerPercent(uint256 rate) external onlyOwnerExec { normalRatePerPercent = rate; } function setHighRatePerPercent(uint256 rate) external onlyOwnerExec { highRatePerPercent = rate; } /// Set hourly yield APR for issuer function setHourlyYieldAPR(address issuer, uint256 aprPercent) external onlyOwnerExecActivator { YieldAccumulator storage yieldAccumulator = hourlyBondYieldAccumulators[issuer]; if (yieldAccumulator.accumulatorFP == 0) { uint256 yieldFP = FP48 + (FP48 * aprPercent) / 100 / (24 * 365); hourlyBondYieldAccumulators[issuer] = YieldAccumulator({ accumulatorFP: FP48, lastUpdated: block.timestamp, hourlyYieldFP: yieldFP }); } else { YieldAccumulator storage yA = getUpdatedHourlyYield( issuer, yieldAccumulator, RATE_UPDATE_WINDOW ); yA.hourlyYieldFP = (FP48 * (100 + aprPercent)) / 100 / (24 * 365); } } /// @dev how much interest has accrued to a borrowed balance over time function applyBorrowInterest( uint256 balance, address issuer, uint256 yieldQuotientFP ) external returns (uint256 balanceWithInterest, uint256 accumulatorFP) { require(isBorrower(msg.sender), "Not approved call"); YieldAccumulator storage yA = borrowYieldAccumulators[issuer]; updateBorrowYieldAccu(yA); accumulatorFP = yA.accumulatorFP; balanceWithInterest = applyInterest( balance, accumulatorFP, yieldQuotientFP ); uint256 deltaAmount = balanceWithInterest - balance; LendingMetadata storage meta = lendingMeta[issuer]; meta.totalBorrowed += deltaAmount; } /// @dev view function to get balance with borrowing interest applied function viewWithBorrowInterest( uint256 balance, address issuer, uint256 yieldQuotientFP ) external view returns (uint256) { uint256 accumulatorFP = viewCumulativeYieldFP( borrowYieldAccumulators[issuer], block.timestamp ); return applyInterest(balance, accumulatorFP, yieldQuotientFP); } /// @dev gets called by router to register if a trader borrows issuers function registerBorrow(address issuer, uint256 amount) external { require(isBorrower(msg.sender), "Not approved borrower"); require(activeIssuers[issuer], "Not approved issuer"); LendingMetadata storage meta = lendingMeta[issuer]; meta.totalBorrowed += amount; getUpdatedHourlyYield( issuer, hourlyBondYieldAccumulators[issuer], BORROW_RATE_UPDATE_WINDOW ); require( meta.totalLending >= meta.totalBorrowed, "Insufficient lending" ); } /// @dev gets called when external sources provide lending function registerLend(address issuer, uint256 amount) external { require(isLender(msg.sender), "Not an approved lender"); require(activeIssuers[issuer], "Not approved issuer"); LendingMetadata storage meta = lendingMeta[issuer]; addToTotalLending(meta, amount); getUpdatedHourlyYield( issuer, hourlyBondYieldAccumulators[issuer], RATE_UPDATE_WINDOW ); } /// @dev gets called when external sources pay withdraw their bobnd function registerWithdrawal(address issuer, uint256 amount) external { require(isLender(msg.sender), "Not an approved lender"); require(activeIssuers[issuer], "Not approved issuer"); LendingMetadata storage meta = lendingMeta[issuer]; subtractFromTotalLending(meta, amount); getUpdatedHourlyYield( issuer, hourlyBondYieldAccumulators[issuer], RATE_UPDATE_WINDOW ); } /// @dev gets called by router if loan is extinguished function payOff(address issuer, uint256 amount) external { require(isBorrower(msg.sender), "Not approved borrower"); lendingMeta[issuer].totalBorrowed -= amount; } /// @dev get the borrow yield for a specific issuer/token function viewAccumulatedBorrowingYieldFP(address issuer) external view returns (uint256) { YieldAccumulator storage yA = borrowYieldAccumulators[issuer]; return viewCumulativeYieldFP(yA, block.timestamp); } function viewAPRPer10k(YieldAccumulator storage yA) internal view returns (uint256) { uint256 hourlyYieldFP = yA.hourlyYieldFP; uint256 aprFP = ((hourlyYieldFP * 10_000 - FP48 * 10_000) * 365 days) / (1 hours); return aprFP / FP48; } /// @dev get current borrowing interest per 10k for a token / issuer function viewBorrowAPRPer10k(address issuer) external view returns (uint256) { return viewAPRPer10k(borrowYieldAccumulators[issuer]); } /// @dev get current lending APR per 10k for a token / issuer function viewHourlyBondAPRPer10k(address issuer) external view returns (uint256) { return viewAPRPer10k(hourlyBondYieldAccumulators[issuer]); } /// @dev In a liquidity crunch make a fallback bond until liquidity is good again function makeFallbackBond( address issuer, address holder, uint256 amount ) external { require(isLender(msg.sender), "Not an approved lender"); _makeHourlyBond(issuer, holder, amount); } /// @dev withdraw an hour bond function withdrawHourlyBond(address issuer, uint256 amount) external { HourlyBond storage bond = hourlyBondAccounts[issuer][msg.sender]; super._withdrawHourlyBond(issuer, bond, amount, msg.sender); if (bond.amount == 0) { delete hourlyBondAccounts[issuer][msg.sender]; } disburse(issuer, msg.sender, amount); IncentiveReporter.subtractFromClaimAmount(issuer, msg.sender, amount); } /// Shut down hourly bond account for `issuer` function closeHourlyBondAccount(address issuer) external { HourlyBond storage bond = hourlyBondAccounts[issuer][msg.sender]; uint256 amount = bond.amount; super._withdrawHourlyBond(issuer, bond, amount, msg.sender); disburse(issuer, msg.sender, amount); delete hourlyBondAccounts[issuer][msg.sender]; IncentiveReporter.subtractFromClaimAmount(issuer, msg.sender, amount); } /// @dev buy hourly bond subscription function buyHourlyBondSubscription(address issuer, uint256 amount) external { require(activeIssuers[issuer], "Not approved issuer"); collectToken(issuer, msg.sender, amount); super._makeHourlyBond(issuer, msg.sender, amount); IncentiveReporter.addToClaimAmount(issuer, msg.sender, amount); } function initBorrowYieldAccumulator(address issuer) external onlyOwnerExecActivator { YieldAccumulator storage yA = borrowYieldAccumulators[issuer]; require(yA.accumulatorFP == 0, "don't re-initialize"); yA.accumulatorFP = FP48; yA.lastUpdated = block.timestamp; yA.hourlyYieldFP = FP48 + (FP48 * borrowMinAPR) / 1000 / (365 * 24); } function setBorrowingFactorPercent(uint256 borrowingFactor) external onlyOwnerExec { borrowingFactorPercent = borrowingFactor; } function issuanceBalance(address issuer) internal view override returns (uint256) { address token = issuerTokens[issuer]; if (token == issuer) { // cross margin return IERC20(token).balanceOf(fund()); } else { return lendingMeta[issuer].totalLending - haircuts[issuer]; } } function disburse( address issuer, address recipient, uint256 amount ) internal { uint256 haircutAmount = haircuts[issuer]; if (haircutAmount > 0 && amount > 0) { uint256 totalLending = lendingMeta[issuer].totalLending; uint256 adjustment = (amount * min(totalLending, haircutAmount)) / totalLending; amount = amount - adjustment; haircuts[issuer] -= adjustment; } address token = issuerTokens[issuer]; Fund(fund()).withdraw(token, recipient, amount); } function collectToken( address issuer, address source, uint256 amount ) internal { Fund(fund()).depositFor(source, issuerTokens[issuer], amount); } function haircut(uint256 amount) external { haircuts[msg.sender] += amount; } function addIncentive( address token, uint256 amount, uint256 endTimestamp ) external onlyOwnerExecActivator { LendingMetadata storage meta = lendingMeta[token]; meta.incentiveEnd = endTimestamp; meta.incentiveTarget = amount; meta.incentiveLastUpdated = block.timestamp; } function disburseIncentive( HourlyBond storage bond, LendingMetadata storage meta, address holder ) internal override { uint256 allocationDelta = meta.cumulIncentiveAllocationFP - bond.incentiveAllocationStart; if (allocationDelta > 0) { uint256 disburseAmount = (allocationDelta * bond.amount) / FP48; Fund(fund()).withdraw(MFI, holder, disburseAmount); bond.incentiveAllocationStart += allocationDelta; } } function withdrawIncentive(address token) external { LendingMetadata storage meta = lendingMeta[token]; updateIncentiveAllocation(meta); disburseIncentive( hourlyBondAccounts[token][msg.sender], meta, msg.sender ); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "../utils/Context.sol"; /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * By default, the owner account will be the one that deploys the contract. This * can later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ abstract contract Ownable is Context { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the deployer as the initial owner. */ constructor () { address msgSender = _msgSender(); _owner = msgSender; emit OwnershipTransferred(address(0), msgSender); } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { require(owner() == _msgSender(), "Ownable: caller is not the owner"); _; } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions anymore. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby removing any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { emit OwnershipTransferred(_owner, address(0)); _owner = address(0); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { require(newOwner != address(0), "Ownable: new owner is the zero address"); emit OwnershipTransferred(_owner, newOwner); _owner = newOwner; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @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 `recipient`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address recipient, 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 `sender` to `recipient` 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 sender, address recipient, uint256 amount) external returns (bool); /** * @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); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "../IERC20.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' // solhint-disable-next-line max-line-length 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)); } } /** * @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 // solhint-disable-next-line max-line-length require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed"); } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /** * @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 * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize, which returns 0 for contracts in // construction, since the code is only stored at the end of the // constructor execution. uint256 size; // solhint-disable-next-line no-inline-assembly assembly { size := extcodesize(account) } return size > 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"); // solhint-disable-next-line avoid-low-level-calls, avoid-call-value (bool success, ) = recipient.call{ value: amount }(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain`call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCall(target, data, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); require(isContract(target), "Address: call to non-contract"); // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory returndata) = target.call{ value: value }(data); return _verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) { require(isContract(target), "Address: static call to non-contract"); // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory returndata) = target.staticcall(data); return _verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { return functionDelegateCall(target, data, "Address: low-level delegate call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) { require(isContract(target), "Address: delegate call to non-contract"); // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory returndata) = target.delegatecall(data); return _verifyCallResult(success, returndata, errorMessage); } function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) { if (success) { return returndata; } else { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly // solhint-disable-next-line no-inline-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } }
// SPDX-License-Identifier: MIT 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) { this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691 return msg.data; } }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.0; import "./RoleAware.sol"; /// @title Base lending behavior abstract contract BaseLending { uint256 constant FP48 = 2**48; uint256 constant ACCUMULATOR_INIT = 10**18; uint256 constant hoursPerYear = 365 days / (1 hours); uint256 constant CHANGE_POINT = 82; uint256 public normalRatePerPercent = (FP48 * 12) / hoursPerYear / CHANGE_POINT / 100; uint256 public highRatePerPercent = (FP48 * (135 - 12)) / hoursPerYear / (100 - CHANGE_POINT) / 100; struct YieldAccumulator { uint256 accumulatorFP; uint256 lastUpdated; uint256 hourlyYieldFP; } struct LendingMetadata { uint256 totalLending; uint256 totalBorrowed; uint256 lendingCap; uint256 cumulIncentiveAllocationFP; uint256 incentiveLastUpdated; uint256 incentiveEnd; uint256 incentiveTarget; } mapping(address => LendingMetadata) public lendingMeta; /// @dev accumulate interest per issuer (like compound indices) mapping(address => YieldAccumulator) public borrowYieldAccumulators; /// @dev simple formula for calculating interest relative to accumulator function applyInterest( uint256 balance, uint256 accumulatorFP, uint256 yieldQuotientFP ) internal pure returns (uint256) { // 1 * FP / FP = 1 return (balance * accumulatorFP) / yieldQuotientFP; } function currentLendingRateFP(uint256 totalLending, uint256 totalBorrowing) internal view returns (uint256 rate) { rate = FP48; uint256 utilizationPercent = totalLending > 0 ? (100 * totalBorrowing) / totalLending : 0; if (utilizationPercent < CHANGE_POINT) { rate += utilizationPercent * normalRatePerPercent; } else { rate += CHANGE_POINT * normalRatePerPercent + (utilizationPercent - CHANGE_POINT) * highRatePerPercent; } } /// @dev minimum function min(uint256 a, uint256 b) internal pure returns (uint256) { if (a > b) { return b; } else { return a; } } /// @dev maximum function max(uint256 a, uint256 b) internal pure returns (uint256) { if (a > b) { return a; } else { return b; } } /// Available tokens to this issuance function issuanceBalance(address issuance) internal view virtual returns (uint256); }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.0; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; import "@openzeppelin/contracts/utils/Address.sol"; import "../interfaces/IWETH.sol"; import "./RoleAware.sol"; /// @title Manage funding contract Fund is RoleAware { using SafeERC20 for IERC20; /// wrapped ether address public immutable WETH; constructor(address _WETH, address _roles) RoleAware(_roles) { WETH = _WETH; } /// Deposit an active token function deposit(address depositToken, uint256 depositAmount) external { IERC20(depositToken).safeTransferFrom( msg.sender, address(this), depositAmount ); } /// Deposit token on behalf of `sender` function depositFor( address sender, address depositToken, uint256 depositAmount ) external { require(isFundTransferer(msg.sender), "Unauthorized deposit"); IERC20(depositToken).safeTransferFrom( sender, address(this), depositAmount ); } /// Deposit to wrapped ether function depositToWETH() external payable { IWETH(WETH).deposit{value: msg.value}(); } // withdrawers role function withdraw( address withdrawalToken, address recipient, uint256 withdrawalAmount ) external { require(isFundTransferer(msg.sender), "Unauthorized withdraw"); IERC20(withdrawalToken).safeTransfer(recipient, withdrawalAmount); } // withdrawers role function withdrawETH(address recipient, uint256 withdrawalAmount) external { require(isFundTransferer(msg.sender), "Unauthorized withdraw"); IWETH(WETH).withdraw(withdrawalAmount); Address.sendValue(payable(recipient), withdrawalAmount); } }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.0; import "./BaseLending.sol"; struct HourlyBond { uint256 amount; uint256 yieldQuotientFP; uint256 moduloHour; uint256 incentiveAllocationStart; } /// @title Here we offer subscriptions to auto-renewing hourly bonds /// Funds are locked in for an 50 minutes per hour, while interest rates float abstract contract HourlyBondSubscriptionLending is BaseLending { mapping(address => YieldAccumulator) hourlyBondYieldAccumulators; uint256 constant RATE_UPDATE_WINDOW = 10 minutes; uint256 public withdrawalWindow = 20 minutes; uint256 constant MAX_HOUR_UPDATE = 4; // issuer => holder => bond record mapping(address => mapping(address => HourlyBond)) public hourlyBondAccounts; uint256 public borrowingFactorPercent = 200; uint256 constant borrowMinAPR = 25; uint256 constant borrowMinHourlyYield = FP48 + (borrowMinAPR * FP48) / 1000 / hoursPerYear; function _makeHourlyBond( address issuer, address holder, uint256 amount ) internal { HourlyBond storage bond = hourlyBondAccounts[issuer][holder]; LendingMetadata storage meta = lendingMeta[issuer]; addToTotalLending(meta, amount); updateHourlyBondAmount(issuer, bond, holder); if (bond.amount == 0) { bond.moduloHour = block.timestamp % (1 hours); } bond.amount += amount; } function updateHourlyBondAmount( address issuer, HourlyBond storage bond, address holder ) internal { uint256 yieldQuotientFP = bond.yieldQuotientFP; YieldAccumulator storage yA = getUpdatedHourlyYield( issuer, hourlyBondYieldAccumulators[issuer], RATE_UPDATE_WINDOW ); LendingMetadata storage meta = lendingMeta[issuer]; if (yieldQuotientFP > 0) { disburseIncentive(bond, meta, holder); uint256 oldAmount = bond.amount; bond.amount = applyInterest( bond.amount, yA.accumulatorFP, yieldQuotientFP ); uint256 deltaAmount = bond.amount - oldAmount; addToTotalLending(meta, deltaAmount); } else { bond.incentiveAllocationStart = meta.cumulIncentiveAllocationFP; } bond.yieldQuotientFP = yA.accumulatorFP; } // Retrieves bond balance for issuer and holder function viewHourlyBondAmount(address issuer, address holder) public view returns (uint256) { HourlyBond storage bond = hourlyBondAccounts[issuer][holder]; uint256 yieldQuotientFP = bond.yieldQuotientFP; uint256 cumulativeYield = viewCumulativeYieldFP( hourlyBondYieldAccumulators[issuer], block.timestamp ); if (yieldQuotientFP > 0) { return applyInterest(bond.amount, cumulativeYield, yieldQuotientFP); } else { return bond.amount; } } function _withdrawHourlyBond( address issuer, HourlyBond storage bond, uint256 amount, address holder ) internal { subtractFromTotalLending(lendingMeta[issuer], amount); updateHourlyBondAmount(issuer, bond, holder); // how far the current hour has advanced (relative to acccount hourly clock) uint256 currentOffset = (block.timestamp - bond.moduloHour) % (1 hours); require( withdrawalWindow >= currentOffset, "Tried withdrawing outside subscription cancellation time window" ); bond.amount -= amount; } function calcCumulativeYieldFP( YieldAccumulator storage yieldAccumulator, uint256 timeDelta ) internal view returns (uint256 accumulatorFP) { uint256 secondsDelta = timeDelta % (1 hours); // linearly interpolate interest for seconds // FP * FP * 1 / (FP * 1) = FP accumulatorFP = yieldAccumulator.accumulatorFP + (yieldAccumulator.accumulatorFP * (yieldAccumulator.hourlyYieldFP - FP48) * secondsDelta) / (FP48 * 1 hours); uint256 hoursDelta = timeDelta / (1 hours); if (hoursDelta > 0) { uint256 accumulatorBeforeFP = accumulatorFP; for (uint256 i = 0; hoursDelta > i && MAX_HOUR_UPDATE > i; i++) { // FP48 * FP48 / FP48 = FP48 accumulatorFP = (accumulatorFP * yieldAccumulator.hourlyYieldFP) / FP48; } // a lot of time has passed if (hoursDelta > MAX_HOUR_UPDATE) { // apply interest in non-compounding way accumulatorFP += ((accumulatorFP - accumulatorBeforeFP) * (hoursDelta - MAX_HOUR_UPDATE)) / MAX_HOUR_UPDATE; } } } /// @dev updates yield accumulators for both borrowing and lending /// issuer address represents a token function updateHourlyYield(address issuer) public returns (uint256 hourlyYield) { return getUpdatedHourlyYield( issuer, hourlyBondYieldAccumulators[issuer], RATE_UPDATE_WINDOW ) .hourlyYieldFP; } /// @dev updates yield accumulators for both borrowing and lending function getUpdatedHourlyYield( address issuer, YieldAccumulator storage accumulator, uint256 window ) internal returns (YieldAccumulator storage) { uint256 lastUpdated = accumulator.lastUpdated; uint256 timeDelta = (block.timestamp - lastUpdated); if (timeDelta > window) { YieldAccumulator storage borrowAccumulator = borrowYieldAccumulators[issuer]; accumulator.accumulatorFP = calcCumulativeYieldFP( accumulator, timeDelta ); LendingMetadata storage meta = lendingMeta[issuer]; accumulator.hourlyYieldFP = currentLendingRateFP( meta.totalLending, meta.totalBorrowed ); accumulator.lastUpdated = block.timestamp; updateBorrowYieldAccu(borrowAccumulator); borrowAccumulator.hourlyYieldFP = max( borrowMinHourlyYield, FP48 + (borrowingFactorPercent * (accumulator.hourlyYieldFP - FP48)) / 100 ); } return accumulator; } function updateBorrowYieldAccu(YieldAccumulator storage borrowAccumulator) internal { uint256 timeDelta = block.timestamp - borrowAccumulator.lastUpdated; if (timeDelta > RATE_UPDATE_WINDOW) { borrowAccumulator.accumulatorFP = calcCumulativeYieldFP( borrowAccumulator, timeDelta ); borrowAccumulator.lastUpdated = block.timestamp; } } function getUpdatedBorrowYieldAccuFP(address issuer) external returns (uint256) { YieldAccumulator storage yA = borrowYieldAccumulators[issuer]; updateBorrowYieldAccu(yA); return yA.accumulatorFP; } function viewCumulativeYieldFP( YieldAccumulator storage yA, uint256 timestamp ) internal view returns (uint256) { uint256 timeDelta = (timestamp - yA.lastUpdated); if (timeDelta > RATE_UPDATE_WINDOW) { return calcCumulativeYieldFP(yA, timeDelta); } else { return yA.accumulatorFP; } } function viewYearlyIncentivePer10k(address token) external view returns (uint256) { LendingMetadata storage meta = lendingMeta[token]; if ( meta.incentiveEnd < block.timestamp || meta.incentiveLastUpdated > meta.incentiveEnd ) { return 0; } else { uint256 timeDelta = meta.incentiveEnd - meta.incentiveLastUpdated; // scale to 1 year return (10_000 * (365 days) * meta.incentiveTarget) / (1 + meta.totalLending * timeDelta); } } function updateIncentiveAllocation(LendingMetadata storage meta) internal { uint256 endTime = min(meta.incentiveEnd, block.timestamp); if (meta.incentiveTarget > 0 && endTime > meta.incentiveLastUpdated) { uint256 timeDelta = endTime - meta.incentiveLastUpdated; uint256 targetDelta = min( meta.incentiveTarget, (timeDelta * meta.incentiveTarget) / (meta.incentiveEnd - meta.incentiveLastUpdated) ); meta.incentiveTarget -= targetDelta; meta.cumulIncentiveAllocationFP += (targetDelta * FP48) / (1 + meta.totalLending); meta.incentiveLastUpdated = block.timestamp; } } function addToTotalLending(LendingMetadata storage meta, uint256 amount) internal { updateIncentiveAllocation(meta); meta.totalLending += amount; } function subtractFromTotalLending( LendingMetadata storage meta, uint256 amount ) internal { updateIncentiveAllocation(meta); meta.totalLending -= amount; } function disburseIncentive( HourlyBond storage bond, LendingMetadata storage meta, address holder ) internal virtual; }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.0; import "./Roles.sol"; /// @title Role management behavior /// Main characters are for service discovery /// Whereas roles are for access control contract RoleAware { Roles public immutable roles; mapping(uint256 => address) public mainCharacterCache; mapping(address => mapping(uint256 => bool)) public roleCache; constructor(address _roles) { require(_roles != address(0), "Please provide valid roles address"); roles = Roles(_roles); } modifier noIntermediary() { require( msg.sender == tx.origin, "Currently no intermediaries allowed for this function call" ); _; } // @dev Throws if called by any account other than the owner or executor modifier onlyOwnerExec() { require( owner() == msg.sender || executor() == msg.sender, "Roles: caller is not the owner" ); _; } modifier onlyOwnerExecDisabler() { require( owner() == msg.sender || executor() == msg.sender || disabler() == msg.sender, "Caller is not the owner, executor or authorized disabler" ); _; } modifier onlyOwnerExecActivator() { require( owner() == msg.sender || executor() == msg.sender || isTokenActivator(msg.sender), "Caller is not the owner, executor or authorized activator" ); _; } function updateRoleCache(uint256 role, address contr) public virtual { roleCache[contr][role] = roles.getRole(role, contr); } function updateMainCharacterCache(uint256 role) public virtual { mainCharacterCache[role] = roles.mainCharacters(role); } function owner() internal view returns (address) { return roles.owner(); } function executor() internal returns (address) { return roles.executor(); } function disabler() internal view returns (address) { return mainCharacterCache[DISABLER]; } function fund() internal view returns (address) { return mainCharacterCache[FUND]; } function lending() internal view returns (address) { return mainCharacterCache[LENDING]; } function marginRouter() internal view returns (address) { return mainCharacterCache[MARGIN_ROUTER]; } function crossMarginTrading() internal view returns (address) { return mainCharacterCache[CROSS_MARGIN_TRADING]; } function feeController() internal view returns (address) { return mainCharacterCache[FEE_CONTROLLER]; } function price() internal view returns (address) { return mainCharacterCache[PRICE_CONTROLLER]; } function admin() internal view returns (address) { return mainCharacterCache[ADMIN]; } function incentiveDistributor() internal view returns (address) { return mainCharacterCache[INCENTIVE_DISTRIBUTION]; } function tokenAdmin() internal view returns (address) { return mainCharacterCache[TOKEN_ADMIN]; } function isBorrower(address contr) internal view returns (bool) { return roleCache[contr][BORROWER]; } function isFundTransferer(address contr) internal view returns (bool) { return roleCache[contr][FUND_TRANSFERER]; } function isMarginTrader(address contr) internal view returns (bool) { return roleCache[contr][MARGIN_TRADER]; } function isFeeSource(address contr) internal view returns (bool) { return roleCache[contr][FEE_SOURCE]; } function isMarginCaller(address contr) internal view returns (bool) { return roleCache[contr][MARGIN_CALLER]; } function isLiquidator(address contr) internal view returns (bool) { return roleCache[contr][LIQUIDATOR]; } function isAuthorizedFundTrader(address contr) internal view returns (bool) { return roleCache[contr][AUTHORIZED_FUND_TRADER]; } function isIncentiveReporter(address contr) internal view returns (bool) { return roleCache[contr][INCENTIVE_REPORTER]; } function isTokenActivator(address contr) internal view returns (bool) { return roleCache[contr][TOKEN_ACTIVATOR]; } function isStakePenalizer(address contr) internal view returns (bool) { return roleCache[contr][STAKE_PENALIZER]; } function isLender(address contr) internal view returns (bool) { return roleCache[contr][LENDER]; } }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.0; import "@openzeppelin/contracts/access/Ownable.sol"; import "../interfaces/IDependencyController.sol"; // we chose not to go with an enum // to make this list easy to extend uint256 constant FUND_TRANSFERER = 1; uint256 constant MARGIN_CALLER = 2; uint256 constant BORROWER = 3; uint256 constant MARGIN_TRADER = 4; uint256 constant FEE_SOURCE = 5; uint256 constant LIQUIDATOR = 6; uint256 constant AUTHORIZED_FUND_TRADER = 7; uint256 constant INCENTIVE_REPORTER = 8; uint256 constant TOKEN_ACTIVATOR = 9; uint256 constant STAKE_PENALIZER = 10; uint256 constant LENDER = 11; uint256 constant FUND = 101; uint256 constant LENDING = 102; uint256 constant MARGIN_ROUTER = 103; uint256 constant CROSS_MARGIN_TRADING = 104; uint256 constant FEE_CONTROLLER = 105; uint256 constant PRICE_CONTROLLER = 106; uint256 constant ADMIN = 107; uint256 constant INCENTIVE_DISTRIBUTION = 108; uint256 constant TOKEN_ADMIN = 109; uint256 constant DISABLER = 1001; uint256 constant DEPENDENCY_CONTROLLER = 1002; /// @title Manage permissions of contracts and ownership of everything /// owned by a multisig wallet (0xEED9D1c6B4cdEcB3af070D85bfd394E7aF179CBd) during /// beta and will then be transfered to governance /// https://github.com/marginswap/governance contract Roles is Ownable { mapping(address => mapping(uint256 => bool)) public roles; mapping(uint256 => address) public mainCharacters; constructor() Ownable() { // token activation from the get-go roles[msg.sender][TOKEN_ACTIVATOR] = true; } /// @dev Throws if called by any account other than the owner. modifier onlyOwnerExecDepController() { require( owner() == msg.sender || executor() == msg.sender || mainCharacters[DEPENDENCY_CONTROLLER] == msg.sender, "Roles: caller is not the owner" ); _; } function giveRole(uint256 role, address actor) external onlyOwnerExecDepController { roles[actor][role] = true; } function removeRole(uint256 role, address actor) external onlyOwnerExecDepController { roles[actor][role] = false; } function setMainCharacter(uint256 role, address actor) external onlyOwnerExecDepController { mainCharacters[role] = actor; } function getRole(uint256 role, address contr) external view returns (bool) { return roles[contr][role]; } /// @dev current executor function executor() public returns (address exec) { address depController = mainCharacters[DEPENDENCY_CONTROLLER]; if (depController != address(0)) { exec = IDependencyController(depController).currentExecutor(); } } }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.0; interface IDependencyController { function currentExecutor() external returns (address); }
pragma solidity >=0.5.0; interface IWETH { function deposit() external payable; function transfer(address to, uint256 value) external returns (bool); function withdraw(uint256) external; }
library IncentiveReporter { event AddToClaim(address topic, address indexed claimant, uint256 amount); event SubtractFromClaim( address topic, address indexed claimant, uint256 amount ); /// Start / increase amount of claim function addToClaimAmount( address topic, address recipient, uint256 claimAmount ) internal { emit AddToClaim(topic, recipient, claimAmount); } /// Decrease amount of claim function subtractFromClaimAmount( address topic, address recipient, uint256 subtractAmount ) internal { emit SubtractFromClaim(topic, recipient, subtractAmount); } }
{ "evmVersion": "istanbul", "libraries": {}, "metadata": { "bytecodeHash": "ipfs", "useLiteralContent": true }, "optimizer": { "enabled": true, "runs": 5000 }, "remappings": [], "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "abi" ] } } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"address","name":"_MFI","type":"address"},{"internalType":"address","name":"_roles","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"MFI","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"issuer","type":"address"}],"name":"activateIssuer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"issuer","type":"address"},{"internalType":"address","name":"token","type":"address"}],"name":"activateIssuer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"activeIssuers","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"endTimestamp","type":"uint256"}],"name":"addIncentive","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"balance","type":"uint256"},{"internalType":"address","name":"issuer","type":"address"},{"internalType":"uint256","name":"yieldQuotientFP","type":"uint256"}],"name":"applyBorrowInterest","outputs":[{"internalType":"uint256","name":"balanceWithInterest","type":"uint256"},{"internalType":"uint256","name":"accumulatorFP","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"borrowYieldAccumulators","outputs":[{"internalType":"uint256","name":"accumulatorFP","type":"uint256"},{"internalType":"uint256","name":"lastUpdated","type":"uint256"},{"internalType":"uint256","name":"hourlyYieldFP","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"borrowingFactorPercent","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"issuer","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"buyHourlyBondSubscription","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"issuer","type":"address"}],"name":"closeHourlyBondAccount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"issuer","type":"address"}],"name":"deactivateIssuer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"issuer","type":"address"}],"name":"getUpdatedBorrowYieldAccuFP","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"haircut","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"haircuts","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"highRatePerPercent","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"hourlyBondAccounts","outputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"yieldQuotientFP","type":"uint256"},{"internalType":"uint256","name":"moduloHour","type":"uint256"},{"internalType":"uint256","name":"incentiveAllocationStart","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"issuer","type":"address"}],"name":"initBorrowYieldAccumulator","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"issuerTokens","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"lendingMeta","outputs":[{"internalType":"uint256","name":"totalLending","type":"uint256"},{"internalType":"uint256","name":"totalBorrowed","type":"uint256"},{"internalType":"uint256","name":"lendingCap","type":"uint256"},{"internalType":"uint256","name":"cumulIncentiveAllocationFP","type":"uint256"},{"internalType":"uint256","name":"incentiveLastUpdated","type":"uint256"},{"internalType":"uint256","name":"incentiveEnd","type":"uint256"},{"internalType":"uint256","name":"incentiveTarget","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"mainCharacterCache","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"issuer","type":"address"},{"internalType":"address","name":"holder","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"makeFallbackBond","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"normalRatePerPercent","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"issuer","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"payOff","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"issuer","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"registerBorrow","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"issuer","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"registerLend","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"issuer","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"registerWithdrawal","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"roleCache","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"roles","outputs":[{"internalType":"contract Roles","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"borrowingFactor","type":"uint256"}],"name":"setBorrowingFactorPercent","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"rate","type":"uint256"}],"name":"setHighRatePerPercent","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"issuer","type":"address"},{"internalType":"uint256","name":"aprPercent","type":"uint256"}],"name":"setHourlyYieldAPR","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"issuer","type":"address"},{"internalType":"uint256","name":"cap","type":"uint256"}],"name":"setLendingCap","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"rate","type":"uint256"}],"name":"setNormalRatePerPercent","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"window","type":"uint256"}],"name":"setWithdrawalWindow","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"issuer","type":"address"}],"name":"updateHourlyYield","outputs":[{"internalType":"uint256","name":"hourlyYield","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"role","type":"uint256"}],"name":"updateMainCharacterCache","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"role","type":"uint256"},{"internalType":"address","name":"contr","type":"address"}],"name":"updateRoleCache","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"issuer","type":"address"}],"name":"viewAccumulatedBorrowingYieldFP","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"issuer","type":"address"}],"name":"viewBorrowAPRPer10k","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"issuer","type":"address"}],"name":"viewHourlyBondAPRPer10k","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"issuer","type":"address"},{"internalType":"address","name":"holder","type":"address"}],"name":"viewHourlyBondAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"balance","type":"uint256"},{"internalType":"address","name":"issuer","type":"address"},{"internalType":"uint256","name":"yieldQuotientFP","type":"uint256"}],"name":"viewWithBorrowInterest","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"viewYearlyIncentivePer10k","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"issuer","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"withdrawHourlyBond","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"withdrawIncentive","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdrawalWindow","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"}]
Contract Creation Code
60c0604052606460526122386200001f6601000000000000600c620001cd565b6200002b9190620001ac565b620000379190620001ac565b620000439190620001ac565b600255606462000055605282620001ef565b6122386200006c6601000000000000607b620001cd565b620000789190620001ac565b620000849190620001ac565b620000909190620001ac565b6003556104b060075560c8600955348015620000ab57600080fd5b5060405162002e9238038062002e92833981016040819052620000ce9162000175565b806001600160a01b038116620001355760405162461bcd60e51b815260206004820152602260248201527f506c656173652070726f766964652076616c696420726f6c6573206164647265604482015261737360f01b606482015260840160405180910390fd5b6001600160601b0319606091821b811660805292901b90911660a052506200021f565b80516001600160a01b03811681146200017057600080fd5b919050565b6000806040838503121562000188578182fd5b620001938362000158565b9150620001a36020840162000158565b90509250929050565b600082620001c857634e487b7160e01b81526012600452602481fd5b500490565b6000816000190483118215151615620001ea57620001ea62000209565b500290565b60008282101562000204576200020462000209565b500390565b634e487b7160e01b600052601160045260246000fd5b60805160601c60a05160601c612c246200026e6000396000818161079f01526126100152600081816103e50152818161084f01528181610bbe01528181612173015261220b0152612c246000f3fe608060405234801561001057600080fd5b506004361061030a5760003560e01c806391b46e051161019c578063db41039f116100ee578063ed29c12b11610097578063f848767311610071578063f8487673146107e7578063f884614b146107fa578063f90889c91461080d5761030a565b8063ed29c12b1461079a578063ee0862bf146107c1578063f51dfe7a146107d45761030a565b8063e69e2662116100c8578063e69e266214610755578063e9c3f77d1461075e578063ebe64bcc146107875761030a565b8063db41039f14610707578063dc683bcf1461071a578063e695fa681461072d5761030a565b8063cc4b26a311610150578063d19bd0a71161012a578063d19bd0a7146106d8578063d2b48934146106e1578063d4437dd8146106f45761030a565b8063cc4b26a314610668578063cd3b5dfb1461067b578063cfc14f53146106c55761030a565b8063ae4479dd11610181578063ae4479dd1461062f578063b42f60db14610642578063bfdeb719146106555761030a565b806391b46e051461059c578063ad037af6146105af5761030a565b806349d0e2ee1161026057806376668b67116102095780637a009135116101e35780637a009135146104fb5780637a1a04df1461050e57806383a042291461053c5761030a565b806376668b67146104ac57806376c308f2146104bf578063797384b2146104c85761030a565b80636d8d36ba1161023a5780636d8d36ba146104735780636e60e2491461048657806372d01257146104995761030a565b806349d0e2ee1461042d5780634b86daab1461044057806364f85ab1146104535761030a565b806328108026116102c2578063392f5f641161029c578063392f5f64146103e0578063447d52ba1461040757806346c87f801461041a5761030a565b806328108026146103795780632a6a897b146103ba57806336953912146103cd5761030a565b806314189db2116102f357806314189db21461033757806316de7a431461035d578063267031b8146103705761030a565b8063071060a61461030f5780630f7c43dc14610324575b600080fd5b61032261031d366004612a4c565b610820565b005b6103226103323660046129cd565b610917565b61034a610345366004612916565b6109a5565b6040519081526020015b60405180910390f35b61032261036b3660046129cd565b6109d0565b61034a60095481565b6103a2610387366004612916565b600a602052600090815260409020546001600160a01b031681565b6040516001600160a01b039091168152602001610354565b6103226103c83660046129cd565b610a62565b6103226103db366004612a4c565b610b01565b6103a27f000000000000000000000000000000000000000000000000000000000000000081565b610322610415366004612a64565b610b7f565b61034a610428366004612916565b610c70565b61032261043b366004612a4c565b610c98565b61032261044e366004612916565b610d16565b61034a610461366004612916565b600b6020526000908152604090205481565b6103226104813660046129cd565b610d23565b61034a610494366004612955565b610e44565b61034a6104a7366004612916565b610ebe565b61034a6104ba366004612a88565b610edf565b61034a60025481565b6104eb6104d6366004612916565b600c6020526000908152604090205460ff1681565b6040519015158152602001610354565b610322610509366004612916565b610f19565b6104eb61051c3660046129cd565b600160209081526000928352604080842090915290825290205460ff1681565b61057c61054a366004612955565b600860209081526000928352604080842090915290825290208054600182015460028301546003909301549192909184565b604080519485526020850193909352918301526060820152608001610354565b6103226105aa366004612a4c565b610fff565b6105fa6105bd366004612916565b6004602081905260009182526040909120805460018201546002830154600384015494840154600585015460069095015493959294919390919087565b604080519788526020880196909652948601939093526060850191909152608084015260a083015260c082015260e001610354565b61032261063d3660046129cd565b61107d565b6103226106503660046129f8565b611172565b61034a610663366004612916565b611269565b610322610676366004612916565b611301565b6106aa610689366004612916565b60056020526000908152604090208054600182015460029092015490919083565b60408051938452602084019290925290820152606001610354565b6103226106d3366004612916565b611480565b61034a60075481565b6103226106ef3660046129cd565b6114d0565b610322610702366004612a4c565b6115b4565b61032261071536600461298d565b6115db565b61034a610728366004612916565b611651565b61074061073b366004612a88565b611681565b60408051928352602083019190915201610354565b61034a60035481565b6103a261076c366004612a4c565b6000602081905290815260409020546001600160a01b031681565b610322610795366004612955565b61176f565b6103a27f000000000000000000000000000000000000000000000000000000000000000081565b6103226107cf3660046129cd565b611891565b61034a6107e2366004612916565b611a12565b6103226107f5366004612a4c565b611a33565b610322610808366004612916565b611ab1565b61032261081b3660046129cd565b611b3a565b6040517fb4ed0b6d000000000000000000000000000000000000000000000000000000008152600481018290527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063b4ed0b6d9060240160206040518083038186803b15801561089957600080fd5b505afa1580156108ad573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108d19190612939565b60009182526020829052604090912080547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b03909216919091179055565b6001600160a01b03821660009081526008602090815260408083203380855292529091209061094b90849083908590611cfe565b805461098a576001600160a01b038316600090815260086020908152604080832033845290915281208181556001810182905560028101829055600301555b610995833384611de4565b6109a0833384611f6d565b505050565b6001600160a01b03811660009081526005602052604081206109c78142611fb9565b9150505b919050565b6001600160a01b0382166000908152600c602052604090205460ff16610a3d5760405162461bcd60e51b815260206004820152601360248201527f4e6f7420617070726f766564206973737565720000000000000000000000000060448201526064015b60405180910390fd5b610a48823383611ffa565b610a538233836120b9565b610a5e82338361212c565b5050565b3360009081526001602090815260408083206003845290915290205460ff16610acd5760405162461bcd60e51b815260206004820152601560248201527f4e6f7420617070726f76656420626f72726f77657200000000000000000000006044820152606401610a34565b6001600160a01b03821660009081526004602052604081206001018054839290610af8908490612b17565b90915550505050565b33610b0a61216f565b6001600160a01b03161480610b2e575033610b23612207565b6001600160a01b0316145b610b7a5760405162461bcd60e51b815260206004820152601e60248201527f526f6c65733a2063616c6c6572206973206e6f7420746865206f776e657200006044820152606401610a34565b600755565b6040517f93552a3d000000000000000000000000000000000000000000000000000000008152600481018390526001600160a01b0382811660248301527f000000000000000000000000000000000000000000000000000000000000000016906393552a3d9060440160206040518083038186803b158015610c0057600080fd5b505afa158015610c14573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c389190612a2c565b6001600160a01b0391909116600090815260016020908152604080832094835293905291909120805460ff1916911515919091179055565b6001600160a01b0381166000908152600560205260408120610c9181612278565b5492915050565b33610ca161216f565b6001600160a01b03161480610cc5575033610cba612207565b6001600160a01b0316145b610d115760405162461bcd60e51b815260206004820152601e60248201527f526f6c65733a2063616c6c6572206973206e6f7420746865206f776e657200006044820152606401610a34565b600355565b610d20818261176f565b50565b336000908152600160209081526040808320600b845290915290205460ff16610d8e5760405162461bcd60e51b815260206004820152601660248201527f4e6f7420616e20617070726f766564206c656e646572000000000000000000006044820152606401610a34565b6001600160a01b0382166000908152600c602052604090205460ff16610df65760405162461bcd60e51b815260206004820152601360248201527f4e6f7420617070726f76656420697373756572000000000000000000000000006044820152606401610a34565b6001600160a01b0382166000908152600460205260409020610e1881836122ac565b6001600160a01b0383166000908152600660205260409020610e3e9084906102586122c9565b50505050565b6001600160a01b038083166000818152600860209081526040808320948616835293815283822060018101549383526006909152928120909291908390610e8b9042611fb9565b90508115610eaa578254610ea09082846123e2565b9350505050610eb8565b5050549050610eb8565b5050505b92915050565b6001600160a01b0381166000908152600660205260408120610eb890612401565b6001600160a01b03821660009081526005602052604081208190610f039042611fb9565b9050610f108582856123e2565b95945050505050565b33610f2261216f565b6001600160a01b03161480610f46575033610f3b612207565b6001600160a01b0316145b80610f6c57503360009081526001602090815260408083206009845290915290205460ff165b610fde5760405162461bcd60e51b815260206004820152603960248201527f43616c6c6572206973206e6f7420746865206f776e65722c206578656375746f60448201527f72206f7220617574686f72697a656420616374697661746f72000000000000006064820152608401610a34565b6001600160a01b03166000908152600c60205260409020805460ff19169055565b3361100861216f565b6001600160a01b0316148061102c575033611021612207565b6001600160a01b0316145b6110785760405162461bcd60e51b815260206004820152601e60248201527f526f6c65733a2063616c6c6572206973206e6f7420746865206f776e657200006044820152606401610a34565b600955565b336000908152600160209081526040808320600b845290915290205460ff166110e85760405162461bcd60e51b815260206004820152601660248201527f4e6f7420616e20617070726f766564206c656e646572000000000000000000006044820152606401610a34565b6001600160a01b0382166000908152600c602052604090205460ff166111505760405162461bcd60e51b815260206004820152601360248201527f4e6f7420617070726f76656420697373756572000000000000000000000000006044820152606401610a34565b6001600160a01b0382166000908152600460205260409020610e188183612461565b3361117b61216f565b6001600160a01b0316148061119f575033611194612207565b6001600160a01b0316145b806111c557503360009081526001602090815260408083206009845290915290205460ff165b6112375760405162461bcd60e51b815260206004820152603960248201527f43616c6c6572206973206e6f7420746865206f776e65722c206578656375746f60448201527f72206f7220617574686f72697a656420616374697661746f72000000000000006064820152608401610a34565b6001600160a01b0390921660009081526004602081905260409091206005810193909355600683019190915542910155565b6001600160a01b0381166000908152600460205260408120600581015442118061129a575080600501548160040154115b156112a95760009150506109cb565b6000816004015482600501546112bf9190612b17565b82549091506112cf908290612ada565b6112da906001612aae565b60068301546112ee9064496cebb800612ada565b6112f89190612ac6565b925050506109cb565b3361130a61216f565b6001600160a01b0316148061132e575033611323612207565b6001600160a01b0316145b8061135457503360009081526001602090815260408083206009845290915290205460ff165b6113c65760405162461bcd60e51b815260206004820152603960248201527f43616c6c6572206973206e6f7420746865206f776e65722c206578656375746f60448201527f72206f7220617574686f72697a656420616374697661746f72000000000000006064820152608401610a34565b6001600160a01b038116600090815260056020526040902080541561142d5760405162461bcd60e51b815260206004820152601360248201527f646f6e27742072652d696e697469616c697a65000000000000000000000000006044820152606401610a34565b6601000000000000808255426001830155612238906103e89061145290601990612ada565b61145c9190612ac6565b6114669190612ac6565b611477906601000000000000612aae565b60029091015550565b6001600160a01b03811660009081526004602052604090206114a18161247e565b6001600160a01b0382166000908152600860209081526040808320338085529252909120610a5e918390612563565b336114d961216f565b6001600160a01b031614806114fd5750336114f2612207565b6001600160a01b0316145b8061152357503360009081526001602090815260408083206009845290915290205460ff165b6115955760405162461bcd60e51b815260206004820152603960248201527f43616c6c6572206973206e6f7420746865206f776e65722c206578656375746f60448201527f72206f7220617574686f72697a656420616374697661746f72000000000000006064820152608401610a34565b6001600160a01b03909116600090815260046020526040902060020155565b336000908152600b6020526040812080548392906115d3908490612aae565b909155505050565b336000908152600160209081526040808320600b845290915290205460ff166116465760405162461bcd60e51b815260206004820152601660248201527f4e6f7420616e20617070726f766564206c656e646572000000000000000000006044820152606401610a34565b6109a08383836120b9565b6001600160a01b03811660009081526006602052604081206116779083906102586122c9565b6002015492915050565b33600090815260016020908152604080832060038452909152812054819060ff166116ee5760405162461bcd60e51b815260206004820152601160248201527f4e6f7420617070726f7665642063616c6c0000000000000000000000000000006044820152606401610a34565b6001600160a01b038416600090815260056020526040902061170f81612278565b8054915061171e8683866123e2565b9250600061172c8785612b17565b6001600160a01b0387166000908152600460205260408120600181018054939450909284929061175d908490612aae565b92505081905550505050935093915050565b3361177861216f565b6001600160a01b0316148061179c575033611791612207565b6001600160a01b0316145b806117c257503360009081526001602090815260408083206009845290915290205460ff165b6118345760405162461bcd60e51b815260206004820152603960248201527f43616c6c6572206973206e6f7420746865206f776e65722c206578656375746f60448201527f72206f7220617574686f72697a656420616374697661746f72000000000000006064820152608401610a34565b6001600160a01b039182166000908152600c60209081526040808320805460ff19166001179055600a90915290208054919092167fffffffffffffffffffffffff0000000000000000000000000000000000000000909116179055565b3360009081526001602090815260408083206003845290915290205460ff166118fc5760405162461bcd60e51b815260206004820152601560248201527f4e6f7420617070726f76656420626f72726f77657200000000000000000000006044820152606401610a34565b6001600160a01b0382166000908152600c602052604090205460ff166119645760405162461bcd60e51b815260206004820152601360248201527f4e6f7420617070726f76656420697373756572000000000000000000000000006044820152606401610a34565b6001600160a01b038216600090815260046020526040812060018101805491928492611991908490612aae565b90915550506001600160a01b03831660009081526006602052604090206119bc908490610e106122c9565b506001810154815410156109a05760405162461bcd60e51b815260206004820152601460248201527f496e73756666696369656e74206c656e64696e670000000000000000000000006044820152606401610a34565b6001600160a01b0381166000908152600560205260408120610eb890612401565b33611a3c61216f565b6001600160a01b03161480611a60575033611a55612207565b6001600160a01b0316145b611aac5760405162461bcd60e51b815260206004820152601e60248201527f526f6c65733a2063616c6c6572206973206e6f7420746865206f776e657200006044820152606401610a34565b600255565b6001600160a01b038116600090815260086020908152604080832033808552925290912080549091611ae890849084908490611cfe565b611af3833383611de4565b6001600160a01b038316600090815260086020908152604080832033808552925282208281556001810183905560028101839055600301919091556109a090849083611f6d565b33611b4361216f565b6001600160a01b03161480611b67575033611b5c612207565b6001600160a01b0316145b80611b8d57503360009081526001602090815260408083206009845290915290205460ff165b611bff5760405162461bcd60e51b815260206004820152603960248201527f43616c6c6572206973206e6f7420746865206f776e65722c206578656375746f60448201527f72206f7220617574686f72697a656420616374697661746f72000000000000006064820152608401610a34565b6001600160a01b03821660009081526006602052604090208054611cae5760006122386064611c35856601000000000000612ada565b611c3f9190612ac6565b611c499190612ac6565b611c5a906601000000000000612aae565b60408051606081018252660100000000000081524260208083019182528284019485526001600160a01b038916600090815260069091529290922090518155905160018201559051600290910155506109a0565b6000611cbd84836102586122c9565b90506122386064611cce8582612aae565b611cdf906601000000000000612ada565b611ce99190612ac6565b611cf39190612ac6565b600290910155505050565b6001600160a01b0384166000908152600460205260409020611d2090836122ac565b611d2b848483612699565b6000610e10846002015442611d409190612b17565b611d4a9190612b67565b9050806007541015611dc45760405162461bcd60e51b815260206004820152603f60248201527f5472696564207769746864726177696e67206f7574736964652073756273637260448201527f697074696f6e2063616e63656c6c6174696f6e2074696d652077696e646f77006064820152608401610a34565b82846000016000828254611dd89190612b17565b90915550505050505050565b6001600160a01b0383166000908152600b60205260409020548015801590611e0c5750600082115b15611e8b576001600160a01b0384166000908152600460205260408120549081611e36818561273f565b611e409086612ada565b611e4a9190612ac6565b9050611e568185612b17565b6001600160a01b0387166000908152600b6020526040812080549296508392909190611e83908490612b17565b909155505050505b6001600160a01b038085166000908152600a602052604090205416611ee1606560009081526020527f4a7203f705e51df4a56139a9b86b4a0970bed7ab7a3446eaffe2289989c1645c546001600160a01b031690565b6040517fd9caed120000000000000000000000000000000000000000000000000000000081526001600160a01b038381166004830152868116602483015260448201869052919091169063d9caed1290606401600060405180830381600087803b158015611f4e57600080fd5b505af1158015611f62573d6000803e3d6000fd5b505050505050505050565b604080516001600160a01b038581168252602082018490528416917f3397b60e3ca1e9c0c75a033d62ab8731e9b2937c0690ae5d7f1bd37886b19d7d91015b60405180910390a2505050565b600080836001015483611fcc9190612b17565b9050610258811115611fea57611fe28482612757565b915050610eb8565b50508154610eb8565b5092915050565b7f4a7203f705e51df4a56139a9b86b4a0970bed7ab7a3446eaffe2289989c1645c546001600160a01b038481166000908152600a60205260408082205481517fb3db428b00000000000000000000000000000000000000000000000000000000815287851660048201529084166024820152604481018690529051929093169263b3db428b926064808301939282900301818387803b15801561209c57600080fd5b505af11580156120b0573d6000803e3d6000fd5b50505050505050565b6001600160a01b038084166000818152600860209081526040808320948716835293815283822092825260049052919091206120f58184612461565b612100858386612699565b815461211857612112610e1042612b67565b60028301555b82826000016000828254611dd89190612aae565b604080516001600160a01b038581168252602082018490528416917f8ec70c9430377a4bba035133e27a5b0f3b9951bc080833f6832bcbbb70a96dba9101611fac565b60007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316638da5cb5b6040518163ffffffff1660e01b815260040160206040518083038186803b1580156121ca57600080fd5b505afa1580156121de573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122029190612939565b905090565b60007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663c34c08e56040518163ffffffff1660e01b8152600401602060405180830381600087803b15801561226457600080fd5b505af11580156121de573d6000803e3d6000fd5b600081600101544261228a9190612b17565b9050610258811115610a5e576122a08282612757565b82554260018301555050565b6122b58261247e565b80826000016000828254610af89190612b17565b6001820154600090816122dc8242612b17565b9050838111156123d8576001600160a01b03861660009081526005602052604090206123088683612757565b86556001600160a01b038716600090815260046020526040902080546001820154612333919061286f565b600288015542600188015561234782612278565b6123cd6122386103e861236266010000000000006019612ada565b61236c9190612ac6565b6123769190612ac6565b612387906601000000000000612aae565b606466010000000000008a600201546123a09190612b17565b6009546123ad9190612ada565b6123b79190612ac6565b6123c8906601000000000000612aae565b6128fe565b826002018190555050505b5092949350505050565b6000816123ef8486612ada565b6123f99190612ac6565b949350505050565b600281015460009081610e106124206601000000000000612710612ada565b61242c84612710612ada565b6124369190612b17565b612444906301e13380612ada565b61244e9190612ac6565b90506123f9660100000000000082612ac6565b61246a8261247e565b80826000016000828254610af89190612aae565b600061248e82600501544261273f565b9050600082600601541180156124a75750816004015481115b15610a5e5760008260040154826124be9190612b17565b905060006124fc8460060154856004015486600501546124de9190612b17565b60068701546124ed9086612ada565b6124f79190612ac6565b61273f565b9050808460060160008282546125129190612b17565b90915550508354612524906001612aae565b612535660100000000000083612ada565b61253f9190612ac6565b8460030160008282546125529190612aae565b909155505042600485015550505050565b6000836003015483600301546125799190612b17565b90508015610e3e5783546000906601000000000000906125999084612ada565b6125a39190612ac6565b90506125e0606560009081526020527f4a7203f705e51df4a56139a9b86b4a0970bed7ab7a3446eaffe2289989c1645c546001600160a01b031690565b6040517fd9caed120000000000000000000000000000000000000000000000000000000081526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000081166004830152858116602483015260448201849052919091169063d9caed1290606401600060405180830381600087803b15801561266d57600080fd5b505af1158015612681573d6000803e3d6000fd5b5050505081856003016000828254611dd89190612aae565b60018201546001600160a01b03841660009081526006602052604081206126c49086906102586122c9565b6001600160a01b03861660009081526004602052604090209091508215612724576126f0858286612563565b84548254612700908290866123e2565b808755600090612711908390612b17565b905061271d8382612461565b505061272f565b600380820154908601555b5054600190930192909255505050565b600081831115612750575080610eb8565b5081610eb8565b600080612766610e1084612b67565b905061277b6601000000000000610e10612ada565b81660100000000000086600201546127939190612b17565b865461279f9190612ada565b6127a99190612ada565b6127b39190612ac6565b84546127bf9190612aae565b915060006127cf610e1085612ac6565b90508015612867578260005b80831180156127ea5750806004115b156128255766010000000000008760020154866128079190612ada565b6128119190612ac6565b94508061281d81612b2e565b9150506127db565b506004821115610eb457600461283b8184612b17565b6128458387612b17565b61284f9190612ada565b6128599190612ac6565b6128639085612aae565b9350505b505092915050565b660100000000000060008361288557600061289b565b83612891846064612ada565b61289b9190612ac6565b905060528110156128c4576002546128b39082612ada565b6128bd9083612aae565b9150611ff3565b6003546128d2605283612b17565b6128dc9190612ada565b6002546128ea906052612ada565b6128f49190612aae565b6123f99083612aae565b60008183111561290f575081610eb8565b5080610eb8565b600060208284031215612927578081fd5b813561293281612bd9565b9392505050565b60006020828403121561294a578081fd5b815161293281612bd9565b60008060408385031215612967578081fd5b823561297281612bd9565b9150602083013561298281612bd9565b809150509250929050565b6000806000606084860312156129a1578081fd5b83356129ac81612bd9565b925060208401356129bc81612bd9565b929592945050506040919091013590565b600080604083850312156129df578182fd5b82356129ea81612bd9565b946020939093013593505050565b600080600060608486031215612a0c578283fd5b8335612a1781612bd9565b95602085013595506040909401359392505050565b600060208284031215612a3d578081fd5b81518015158114612932578182fd5b600060208284031215612a5d578081fd5b5035919050565b60008060408385031215612a76578182fd5b82359150602083013561298281612bd9565b600080600060608486031215612a9c578283fd5b8335925060208401356129bc81612bd9565b60008219821115612ac157612ac1612b7b565b500190565b600082612ad557612ad5612baa565b500490565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615612b1257612b12612b7b565b500290565b600082821015612b2957612b29612b7b565b500390565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff821415612b6057612b60612b7b565b5060010190565b600082612b7657612b76612baa565b500690565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6001600160a01b0381168114610d2057600080fdfea26469706673582212208a451470ba8ee8ff877e735ffaac79f28bd8ba5c62f6730bd169f0963e1d946e64736f6c63430008030033000000000000000000000000aa4e3edb11afa93c41db59842b29de64b72e355b000000000000000000000000c6d13a49cdc5afc7798dd0eba7698db9bfcc1d8c
Deployed Bytecode
0x608060405234801561001057600080fd5b506004361061030a5760003560e01c806391b46e051161019c578063db41039f116100ee578063ed29c12b11610097578063f848767311610071578063f8487673146107e7578063f884614b146107fa578063f90889c91461080d5761030a565b8063ed29c12b1461079a578063ee0862bf146107c1578063f51dfe7a146107d45761030a565b8063e69e2662116100c8578063e69e266214610755578063e9c3f77d1461075e578063ebe64bcc146107875761030a565b8063db41039f14610707578063dc683bcf1461071a578063e695fa681461072d5761030a565b8063cc4b26a311610150578063d19bd0a71161012a578063d19bd0a7146106d8578063d2b48934146106e1578063d4437dd8146106f45761030a565b8063cc4b26a314610668578063cd3b5dfb1461067b578063cfc14f53146106c55761030a565b8063ae4479dd11610181578063ae4479dd1461062f578063b42f60db14610642578063bfdeb719146106555761030a565b806391b46e051461059c578063ad037af6146105af5761030a565b806349d0e2ee1161026057806376668b67116102095780637a009135116101e35780637a009135146104fb5780637a1a04df1461050e57806383a042291461053c5761030a565b806376668b67146104ac57806376c308f2146104bf578063797384b2146104c85761030a565b80636d8d36ba1161023a5780636d8d36ba146104735780636e60e2491461048657806372d01257146104995761030a565b806349d0e2ee1461042d5780634b86daab1461044057806364f85ab1146104535761030a565b806328108026116102c2578063392f5f641161029c578063392f5f64146103e0578063447d52ba1461040757806346c87f801461041a5761030a565b806328108026146103795780632a6a897b146103ba57806336953912146103cd5761030a565b806314189db2116102f357806314189db21461033757806316de7a431461035d578063267031b8146103705761030a565b8063071060a61461030f5780630f7c43dc14610324575b600080fd5b61032261031d366004612a4c565b610820565b005b6103226103323660046129cd565b610917565b61034a610345366004612916565b6109a5565b6040519081526020015b60405180910390f35b61032261036b3660046129cd565b6109d0565b61034a60095481565b6103a2610387366004612916565b600a602052600090815260409020546001600160a01b031681565b6040516001600160a01b039091168152602001610354565b6103226103c83660046129cd565b610a62565b6103226103db366004612a4c565b610b01565b6103a27f000000000000000000000000c6d13a49cdc5afc7798dd0eba7698db9bfcc1d8c81565b610322610415366004612a64565b610b7f565b61034a610428366004612916565b610c70565b61032261043b366004612a4c565b610c98565b61032261044e366004612916565b610d16565b61034a610461366004612916565b600b6020526000908152604090205481565b6103226104813660046129cd565b610d23565b61034a610494366004612955565b610e44565b61034a6104a7366004612916565b610ebe565b61034a6104ba366004612a88565b610edf565b61034a60025481565b6104eb6104d6366004612916565b600c6020526000908152604090205460ff1681565b6040519015158152602001610354565b610322610509366004612916565b610f19565b6104eb61051c3660046129cd565b600160209081526000928352604080842090915290825290205460ff1681565b61057c61054a366004612955565b600860209081526000928352604080842090915290825290208054600182015460028301546003909301549192909184565b604080519485526020850193909352918301526060820152608001610354565b6103226105aa366004612a4c565b610fff565b6105fa6105bd366004612916565b6004602081905260009182526040909120805460018201546002830154600384015494840154600585015460069095015493959294919390919087565b604080519788526020880196909652948601939093526060850191909152608084015260a083015260c082015260e001610354565b61032261063d3660046129cd565b61107d565b6103226106503660046129f8565b611172565b61034a610663366004612916565b611269565b610322610676366004612916565b611301565b6106aa610689366004612916565b60056020526000908152604090208054600182015460029092015490919083565b60408051938452602084019290925290820152606001610354565b6103226106d3366004612916565b611480565b61034a60075481565b6103226106ef3660046129cd565b6114d0565b610322610702366004612a4c565b6115b4565b61032261071536600461298d565b6115db565b61034a610728366004612916565b611651565b61074061073b366004612a88565b611681565b60408051928352602083019190915201610354565b61034a60035481565b6103a261076c366004612a4c565b6000602081905290815260409020546001600160a01b031681565b610322610795366004612955565b61176f565b6103a27f000000000000000000000000aa4e3edb11afa93c41db59842b29de64b72e355b81565b6103226107cf3660046129cd565b611891565b61034a6107e2366004612916565b611a12565b6103226107f5366004612a4c565b611a33565b610322610808366004612916565b611ab1565b61032261081b3660046129cd565b611b3a565b6040517fb4ed0b6d000000000000000000000000000000000000000000000000000000008152600481018290527f000000000000000000000000c6d13a49cdc5afc7798dd0eba7698db9bfcc1d8c6001600160a01b03169063b4ed0b6d9060240160206040518083038186803b15801561089957600080fd5b505afa1580156108ad573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108d19190612939565b60009182526020829052604090912080547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b03909216919091179055565b6001600160a01b03821660009081526008602090815260408083203380855292529091209061094b90849083908590611cfe565b805461098a576001600160a01b038316600090815260086020908152604080832033845290915281208181556001810182905560028101829055600301555b610995833384611de4565b6109a0833384611f6d565b505050565b6001600160a01b03811660009081526005602052604081206109c78142611fb9565b9150505b919050565b6001600160a01b0382166000908152600c602052604090205460ff16610a3d5760405162461bcd60e51b815260206004820152601360248201527f4e6f7420617070726f766564206973737565720000000000000000000000000060448201526064015b60405180910390fd5b610a48823383611ffa565b610a538233836120b9565b610a5e82338361212c565b5050565b3360009081526001602090815260408083206003845290915290205460ff16610acd5760405162461bcd60e51b815260206004820152601560248201527f4e6f7420617070726f76656420626f72726f77657200000000000000000000006044820152606401610a34565b6001600160a01b03821660009081526004602052604081206001018054839290610af8908490612b17565b90915550505050565b33610b0a61216f565b6001600160a01b03161480610b2e575033610b23612207565b6001600160a01b0316145b610b7a5760405162461bcd60e51b815260206004820152601e60248201527f526f6c65733a2063616c6c6572206973206e6f7420746865206f776e657200006044820152606401610a34565b600755565b6040517f93552a3d000000000000000000000000000000000000000000000000000000008152600481018390526001600160a01b0382811660248301527f000000000000000000000000c6d13a49cdc5afc7798dd0eba7698db9bfcc1d8c16906393552a3d9060440160206040518083038186803b158015610c0057600080fd5b505afa158015610c14573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c389190612a2c565b6001600160a01b0391909116600090815260016020908152604080832094835293905291909120805460ff1916911515919091179055565b6001600160a01b0381166000908152600560205260408120610c9181612278565b5492915050565b33610ca161216f565b6001600160a01b03161480610cc5575033610cba612207565b6001600160a01b0316145b610d115760405162461bcd60e51b815260206004820152601e60248201527f526f6c65733a2063616c6c6572206973206e6f7420746865206f776e657200006044820152606401610a34565b600355565b610d20818261176f565b50565b336000908152600160209081526040808320600b845290915290205460ff16610d8e5760405162461bcd60e51b815260206004820152601660248201527f4e6f7420616e20617070726f766564206c656e646572000000000000000000006044820152606401610a34565b6001600160a01b0382166000908152600c602052604090205460ff16610df65760405162461bcd60e51b815260206004820152601360248201527f4e6f7420617070726f76656420697373756572000000000000000000000000006044820152606401610a34565b6001600160a01b0382166000908152600460205260409020610e1881836122ac565b6001600160a01b0383166000908152600660205260409020610e3e9084906102586122c9565b50505050565b6001600160a01b038083166000818152600860209081526040808320948616835293815283822060018101549383526006909152928120909291908390610e8b9042611fb9565b90508115610eaa578254610ea09082846123e2565b9350505050610eb8565b5050549050610eb8565b5050505b92915050565b6001600160a01b0381166000908152600660205260408120610eb890612401565b6001600160a01b03821660009081526005602052604081208190610f039042611fb9565b9050610f108582856123e2565b95945050505050565b33610f2261216f565b6001600160a01b03161480610f46575033610f3b612207565b6001600160a01b0316145b80610f6c57503360009081526001602090815260408083206009845290915290205460ff165b610fde5760405162461bcd60e51b815260206004820152603960248201527f43616c6c6572206973206e6f7420746865206f776e65722c206578656375746f60448201527f72206f7220617574686f72697a656420616374697661746f72000000000000006064820152608401610a34565b6001600160a01b03166000908152600c60205260409020805460ff19169055565b3361100861216f565b6001600160a01b0316148061102c575033611021612207565b6001600160a01b0316145b6110785760405162461bcd60e51b815260206004820152601e60248201527f526f6c65733a2063616c6c6572206973206e6f7420746865206f776e657200006044820152606401610a34565b600955565b336000908152600160209081526040808320600b845290915290205460ff166110e85760405162461bcd60e51b815260206004820152601660248201527f4e6f7420616e20617070726f766564206c656e646572000000000000000000006044820152606401610a34565b6001600160a01b0382166000908152600c602052604090205460ff166111505760405162461bcd60e51b815260206004820152601360248201527f4e6f7420617070726f76656420697373756572000000000000000000000000006044820152606401610a34565b6001600160a01b0382166000908152600460205260409020610e188183612461565b3361117b61216f565b6001600160a01b0316148061119f575033611194612207565b6001600160a01b0316145b806111c557503360009081526001602090815260408083206009845290915290205460ff165b6112375760405162461bcd60e51b815260206004820152603960248201527f43616c6c6572206973206e6f7420746865206f776e65722c206578656375746f60448201527f72206f7220617574686f72697a656420616374697661746f72000000000000006064820152608401610a34565b6001600160a01b0390921660009081526004602081905260409091206005810193909355600683019190915542910155565b6001600160a01b0381166000908152600460205260408120600581015442118061129a575080600501548160040154115b156112a95760009150506109cb565b6000816004015482600501546112bf9190612b17565b82549091506112cf908290612ada565b6112da906001612aae565b60068301546112ee9064496cebb800612ada565b6112f89190612ac6565b925050506109cb565b3361130a61216f565b6001600160a01b0316148061132e575033611323612207565b6001600160a01b0316145b8061135457503360009081526001602090815260408083206009845290915290205460ff165b6113c65760405162461bcd60e51b815260206004820152603960248201527f43616c6c6572206973206e6f7420746865206f776e65722c206578656375746f60448201527f72206f7220617574686f72697a656420616374697661746f72000000000000006064820152608401610a34565b6001600160a01b038116600090815260056020526040902080541561142d5760405162461bcd60e51b815260206004820152601360248201527f646f6e27742072652d696e697469616c697a65000000000000000000000000006044820152606401610a34565b6601000000000000808255426001830155612238906103e89061145290601990612ada565b61145c9190612ac6565b6114669190612ac6565b611477906601000000000000612aae565b60029091015550565b6001600160a01b03811660009081526004602052604090206114a18161247e565b6001600160a01b0382166000908152600860209081526040808320338085529252909120610a5e918390612563565b336114d961216f565b6001600160a01b031614806114fd5750336114f2612207565b6001600160a01b0316145b8061152357503360009081526001602090815260408083206009845290915290205460ff165b6115955760405162461bcd60e51b815260206004820152603960248201527f43616c6c6572206973206e6f7420746865206f776e65722c206578656375746f60448201527f72206f7220617574686f72697a656420616374697661746f72000000000000006064820152608401610a34565b6001600160a01b03909116600090815260046020526040902060020155565b336000908152600b6020526040812080548392906115d3908490612aae565b909155505050565b336000908152600160209081526040808320600b845290915290205460ff166116465760405162461bcd60e51b815260206004820152601660248201527f4e6f7420616e20617070726f766564206c656e646572000000000000000000006044820152606401610a34565b6109a08383836120b9565b6001600160a01b03811660009081526006602052604081206116779083906102586122c9565b6002015492915050565b33600090815260016020908152604080832060038452909152812054819060ff166116ee5760405162461bcd60e51b815260206004820152601160248201527f4e6f7420617070726f7665642063616c6c0000000000000000000000000000006044820152606401610a34565b6001600160a01b038416600090815260056020526040902061170f81612278565b8054915061171e8683866123e2565b9250600061172c8785612b17565b6001600160a01b0387166000908152600460205260408120600181018054939450909284929061175d908490612aae565b92505081905550505050935093915050565b3361177861216f565b6001600160a01b0316148061179c575033611791612207565b6001600160a01b0316145b806117c257503360009081526001602090815260408083206009845290915290205460ff165b6118345760405162461bcd60e51b815260206004820152603960248201527f43616c6c6572206973206e6f7420746865206f776e65722c206578656375746f60448201527f72206f7220617574686f72697a656420616374697661746f72000000000000006064820152608401610a34565b6001600160a01b039182166000908152600c60209081526040808320805460ff19166001179055600a90915290208054919092167fffffffffffffffffffffffff0000000000000000000000000000000000000000909116179055565b3360009081526001602090815260408083206003845290915290205460ff166118fc5760405162461bcd60e51b815260206004820152601560248201527f4e6f7420617070726f76656420626f72726f77657200000000000000000000006044820152606401610a34565b6001600160a01b0382166000908152600c602052604090205460ff166119645760405162461bcd60e51b815260206004820152601360248201527f4e6f7420617070726f76656420697373756572000000000000000000000000006044820152606401610a34565b6001600160a01b038216600090815260046020526040812060018101805491928492611991908490612aae565b90915550506001600160a01b03831660009081526006602052604090206119bc908490610e106122c9565b506001810154815410156109a05760405162461bcd60e51b815260206004820152601460248201527f496e73756666696369656e74206c656e64696e670000000000000000000000006044820152606401610a34565b6001600160a01b0381166000908152600560205260408120610eb890612401565b33611a3c61216f565b6001600160a01b03161480611a60575033611a55612207565b6001600160a01b0316145b611aac5760405162461bcd60e51b815260206004820152601e60248201527f526f6c65733a2063616c6c6572206973206e6f7420746865206f776e657200006044820152606401610a34565b600255565b6001600160a01b038116600090815260086020908152604080832033808552925290912080549091611ae890849084908490611cfe565b611af3833383611de4565b6001600160a01b038316600090815260086020908152604080832033808552925282208281556001810183905560028101839055600301919091556109a090849083611f6d565b33611b4361216f565b6001600160a01b03161480611b67575033611b5c612207565b6001600160a01b0316145b80611b8d57503360009081526001602090815260408083206009845290915290205460ff165b611bff5760405162461bcd60e51b815260206004820152603960248201527f43616c6c6572206973206e6f7420746865206f776e65722c206578656375746f60448201527f72206f7220617574686f72697a656420616374697661746f72000000000000006064820152608401610a34565b6001600160a01b03821660009081526006602052604090208054611cae5760006122386064611c35856601000000000000612ada565b611c3f9190612ac6565b611c499190612ac6565b611c5a906601000000000000612aae565b60408051606081018252660100000000000081524260208083019182528284019485526001600160a01b038916600090815260069091529290922090518155905160018201559051600290910155506109a0565b6000611cbd84836102586122c9565b90506122386064611cce8582612aae565b611cdf906601000000000000612ada565b611ce99190612ac6565b611cf39190612ac6565b600290910155505050565b6001600160a01b0384166000908152600460205260409020611d2090836122ac565b611d2b848483612699565b6000610e10846002015442611d409190612b17565b611d4a9190612b67565b9050806007541015611dc45760405162461bcd60e51b815260206004820152603f60248201527f5472696564207769746864726177696e67206f7574736964652073756273637260448201527f697074696f6e2063616e63656c6c6174696f6e2074696d652077696e646f77006064820152608401610a34565b82846000016000828254611dd89190612b17565b90915550505050505050565b6001600160a01b0383166000908152600b60205260409020548015801590611e0c5750600082115b15611e8b576001600160a01b0384166000908152600460205260408120549081611e36818561273f565b611e409086612ada565b611e4a9190612ac6565b9050611e568185612b17565b6001600160a01b0387166000908152600b6020526040812080549296508392909190611e83908490612b17565b909155505050505b6001600160a01b038085166000908152600a602052604090205416611ee1606560009081526020527f4a7203f705e51df4a56139a9b86b4a0970bed7ab7a3446eaffe2289989c1645c546001600160a01b031690565b6040517fd9caed120000000000000000000000000000000000000000000000000000000081526001600160a01b038381166004830152868116602483015260448201869052919091169063d9caed1290606401600060405180830381600087803b158015611f4e57600080fd5b505af1158015611f62573d6000803e3d6000fd5b505050505050505050565b604080516001600160a01b038581168252602082018490528416917f3397b60e3ca1e9c0c75a033d62ab8731e9b2937c0690ae5d7f1bd37886b19d7d91015b60405180910390a2505050565b600080836001015483611fcc9190612b17565b9050610258811115611fea57611fe28482612757565b915050610eb8565b50508154610eb8565b5092915050565b7f4a7203f705e51df4a56139a9b86b4a0970bed7ab7a3446eaffe2289989c1645c546001600160a01b038481166000908152600a60205260408082205481517fb3db428b00000000000000000000000000000000000000000000000000000000815287851660048201529084166024820152604481018690529051929093169263b3db428b926064808301939282900301818387803b15801561209c57600080fd5b505af11580156120b0573d6000803e3d6000fd5b50505050505050565b6001600160a01b038084166000818152600860209081526040808320948716835293815283822092825260049052919091206120f58184612461565b612100858386612699565b815461211857612112610e1042612b67565b60028301555b82826000016000828254611dd89190612aae565b604080516001600160a01b038581168252602082018490528416917f8ec70c9430377a4bba035133e27a5b0f3b9951bc080833f6832bcbbb70a96dba9101611fac565b60007f000000000000000000000000c6d13a49cdc5afc7798dd0eba7698db9bfcc1d8c6001600160a01b0316638da5cb5b6040518163ffffffff1660e01b815260040160206040518083038186803b1580156121ca57600080fd5b505afa1580156121de573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122029190612939565b905090565b60007f000000000000000000000000c6d13a49cdc5afc7798dd0eba7698db9bfcc1d8c6001600160a01b031663c34c08e56040518163ffffffff1660e01b8152600401602060405180830381600087803b15801561226457600080fd5b505af11580156121de573d6000803e3d6000fd5b600081600101544261228a9190612b17565b9050610258811115610a5e576122a08282612757565b82554260018301555050565b6122b58261247e565b80826000016000828254610af89190612b17565b6001820154600090816122dc8242612b17565b9050838111156123d8576001600160a01b03861660009081526005602052604090206123088683612757565b86556001600160a01b038716600090815260046020526040902080546001820154612333919061286f565b600288015542600188015561234782612278565b6123cd6122386103e861236266010000000000006019612ada565b61236c9190612ac6565b6123769190612ac6565b612387906601000000000000612aae565b606466010000000000008a600201546123a09190612b17565b6009546123ad9190612ada565b6123b79190612ac6565b6123c8906601000000000000612aae565b6128fe565b826002018190555050505b5092949350505050565b6000816123ef8486612ada565b6123f99190612ac6565b949350505050565b600281015460009081610e106124206601000000000000612710612ada565b61242c84612710612ada565b6124369190612b17565b612444906301e13380612ada565b61244e9190612ac6565b90506123f9660100000000000082612ac6565b61246a8261247e565b80826000016000828254610af89190612aae565b600061248e82600501544261273f565b9050600082600601541180156124a75750816004015481115b15610a5e5760008260040154826124be9190612b17565b905060006124fc8460060154856004015486600501546124de9190612b17565b60068701546124ed9086612ada565b6124f79190612ac6565b61273f565b9050808460060160008282546125129190612b17565b90915550508354612524906001612aae565b612535660100000000000083612ada565b61253f9190612ac6565b8460030160008282546125529190612aae565b909155505042600485015550505050565b6000836003015483600301546125799190612b17565b90508015610e3e5783546000906601000000000000906125999084612ada565b6125a39190612ac6565b90506125e0606560009081526020527f4a7203f705e51df4a56139a9b86b4a0970bed7ab7a3446eaffe2289989c1645c546001600160a01b031690565b6040517fd9caed120000000000000000000000000000000000000000000000000000000081526001600160a01b037f000000000000000000000000aa4e3edb11afa93c41db59842b29de64b72e355b81166004830152858116602483015260448201849052919091169063d9caed1290606401600060405180830381600087803b15801561266d57600080fd5b505af1158015612681573d6000803e3d6000fd5b5050505081856003016000828254611dd89190612aae565b60018201546001600160a01b03841660009081526006602052604081206126c49086906102586122c9565b6001600160a01b03861660009081526004602052604090209091508215612724576126f0858286612563565b84548254612700908290866123e2565b808755600090612711908390612b17565b905061271d8382612461565b505061272f565b600380820154908601555b5054600190930192909255505050565b600081831115612750575080610eb8565b5081610eb8565b600080612766610e1084612b67565b905061277b6601000000000000610e10612ada565b81660100000000000086600201546127939190612b17565b865461279f9190612ada565b6127a99190612ada565b6127b39190612ac6565b84546127bf9190612aae565b915060006127cf610e1085612ac6565b90508015612867578260005b80831180156127ea5750806004115b156128255766010000000000008760020154866128079190612ada565b6128119190612ac6565b94508061281d81612b2e565b9150506127db565b506004821115610eb457600461283b8184612b17565b6128458387612b17565b61284f9190612ada565b6128599190612ac6565b6128639085612aae565b9350505b505092915050565b660100000000000060008361288557600061289b565b83612891846064612ada565b61289b9190612ac6565b905060528110156128c4576002546128b39082612ada565b6128bd9083612aae565b9150611ff3565b6003546128d2605283612b17565b6128dc9190612ada565b6002546128ea906052612ada565b6128f49190612aae565b6123f99083612aae565b60008183111561290f575081610eb8565b5080610eb8565b600060208284031215612927578081fd5b813561293281612bd9565b9392505050565b60006020828403121561294a578081fd5b815161293281612bd9565b60008060408385031215612967578081fd5b823561297281612bd9565b9150602083013561298281612bd9565b809150509250929050565b6000806000606084860312156129a1578081fd5b83356129ac81612bd9565b925060208401356129bc81612bd9565b929592945050506040919091013590565b600080604083850312156129df578182fd5b82356129ea81612bd9565b946020939093013593505050565b600080600060608486031215612a0c578283fd5b8335612a1781612bd9565b95602085013595506040909401359392505050565b600060208284031215612a3d578081fd5b81518015158114612932578182fd5b600060208284031215612a5d578081fd5b5035919050565b60008060408385031215612a76578182fd5b82359150602083013561298281612bd9565b600080600060608486031215612a9c578283fd5b8335925060208401356129bc81612bd9565b60008219821115612ac157612ac1612b7b565b500190565b600082612ad557612ad5612baa565b500490565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615612b1257612b12612b7b565b500290565b600082821015612b2957612b29612b7b565b500390565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff821415612b6057612b60612b7b565b5060010190565b600082612b7657612b76612baa565b500690565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6001600160a01b0381168114610d2057600080fdfea26469706673582212208a451470ba8ee8ff877e735ffaac79f28bd8ba5c62f6730bd169f0963e1d946e64736f6c63430008030033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000aa4e3edb11afa93c41db59842b29de64b72e355b000000000000000000000000c6d13a49cdc5afc7798dd0eba7698db9bfcc1d8c
-----Decoded View---------------
Arg [0] : _MFI (address): 0xAa4e3edb11AFa93c41db59842b29de64b72E355B
Arg [1] : _roles (address): 0xC6D13A49cdC5Afc7798dd0eBA7698DB9BFCc1D8c
-----Encoded View---------------
2 Constructor Arguments found :
Arg [0] : 000000000000000000000000aa4e3edb11afa93c41db59842b29de64b72e355b
Arg [1] : 000000000000000000000000c6d13a49cdc5afc7798dd0eba7698db9bfcc1d8c
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.