More Info
Private Name Tags
ContractCreator
Latest 25 from a total of 53 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Settle | 19042368 | 403 days ago | IN | 0 ETH | 0.00279139 | ||||
Mint | 19037206 | 403 days ago | IN | 0 ETH | 0.00969089 | ||||
Settle | 19028322 | 405 days ago | IN | 0 ETH | 0.0021515 | ||||
Settle | 17921385 | 560 days ago | IN | 0 ETH | 0.00126975 | ||||
Settle | 17921383 | 560 days ago | IN | 0 ETH | 0.00125565 | ||||
Settle | 17921381 | 560 days ago | IN | 0 ETH | 0.00240618 | ||||
Settle | 17828345 | 573 days ago | IN | 0 ETH | 0.00194875 | ||||
Settle | 17473041 | 623 days ago | IN | 0 ETH | 0.00098402 | ||||
Mint | 17423979 | 630 days ago | IN | 0 ETH | 0.00692348 | ||||
Mint | 17423211 | 630 days ago | IN | 0 ETH | 0.00612912 | ||||
Mint | 17423206 | 630 days ago | IN | 0 ETH | 0.00619846 | ||||
Mint | 17423201 | 630 days ago | IN | 0 ETH | 0.00612716 | ||||
Mint | 17423195 | 630 days ago | IN | 0 ETH | 0.00776691 | ||||
Mint | 17254237 | 653 days ago | IN | 0 ETH | 0.00963949 | ||||
Settle | 17232225 | 657 days ago | IN | 0 ETH | 0.00932062 | ||||
Mint | 17198416 | 661 days ago | IN | 0 ETH | 0.01956589 | ||||
Mint | 17198312 | 661 days ago | IN | 0 ETH | 0.02099694 | ||||
Mint | 17154888 | 667 days ago | IN | 0 ETH | 0.00706075 | ||||
Mint | 17083060 | 678 days ago | IN | 0 ETH | 0.01508612 | ||||
Mint | 16877789 | 707 days ago | IN | 0 ETH | 0.00475776 | ||||
Mint | 16843059 | 712 days ago | IN | 0 ETH | 0.00438944 | ||||
Mint | 16836043 | 713 days ago | IN | 0 ETH | 0.00422652 | ||||
Mint | 16785759 | 720 days ago | IN | 0 ETH | 0.01051199 | ||||
Mint | 16777675 | 721 days ago | IN | 0 ETH | 0.00646414 | ||||
Mint | 16666321 | 736 days ago | IN | 0 ETH | 0.00433462 |
Loading...
Loading
Contract Source Code Verified (Exact Match)
Contract Name:
Raises
Compiler Version
v0.8.17+commit.8df45f5f
Optimization Enabled:
Yes with 200 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT pragma solidity 0.8.17; import {ReentrancyGuard} from "openzeppelin-contracts/security/ReentrancyGuard.sol"; import {Address} from "openzeppelin-contracts/utils/Address.sol"; import {MerkleProof} from "openzeppelin-contracts/utils/cryptography/MerkleProof.sol"; import {IERC20} from "openzeppelin-contracts/token/ERC20/IERC20.sol"; import {SafeERC20} from "openzeppelin-contracts/token/ERC20/utils/SafeERC20.sol"; import {Math} from "openzeppelin-contracts/utils/math/Math.sol"; import {RaiseParams, Raise, RaiseState, RaiseTokens, RaiseTimestamps, Phase, FeeSchedule} from "./structs/Raise.sol"; import {TierParams, TierType, Tier} from "./structs/Tier.sol"; import {RaiseValidator} from "./libraries/validators/RaiseValidator.sol"; import {TierValidator} from "./libraries/validators/TierValidator.sol"; import {Phases} from "./libraries/Phases.sol"; import {IRaises} from "./interfaces/IRaises.sol"; import {IProjects} from "./interfaces/IProjects.sol"; import {IMinter} from "./interfaces/IMinter.sol"; import {ITokens} from "./interfaces/ITokens.sol"; import {ITokenAuth} from "./interfaces/ITokenAuth.sol"; import {ITokenDeployer} from "./interfaces/ITokenDeployer.sol"; import {IControllable} from "./interfaces/IControllable.sol"; import {IPausable} from "./interfaces/IPausable.sol"; import {Controllable} from "./abstract/Controllable.sol"; import {Pausable} from "./abstract/Pausable.sol"; import {RaiseToken} from "./libraries/RaiseToken.sol"; import {Fees} from "./libraries/Fees.sol"; import {ETH} from "./constants/Constants.sol"; /// @title Raises - Crowdfunding mint module /// @notice Patrons interact with this contract to mint and redeem raise tokens /// in support of projects. contract Raises is IRaises, Controllable, Pausable, ReentrancyGuard { using RaiseValidator for RaiseParams; using TierValidator for TierParams; using Phases for Raise; using Fees for FeeSchedule; using SafeERC20 for IERC20; using Address for address payable; string public constant NAME = "Raises"; string public constant VERSION = "0.0.1"; address public creators; address public projects; address public minter; address public deployer; address public tokens; address public tokenAuth; FeeSchedule public feeSchedule = FeeSchedule({fanFee: 500, brandFee: 2500}); // projectId => totalRaises mapping(uint32 => uint32) public totalRaises; // projectId => raiseId => Raise mapping(uint32 => mapping(uint32 => Raise)) public raises; // projectId => raiseId => Tier[] mapping(uint32 => mapping(uint32 => Tier[])) public tiers; // projectId => raiseId => tierId => minter address => count mapping(uint32 => mapping(uint32 => mapping(uint32 => mapping(address => uint256)))) public mints; // token address => accrued protocol fees mapping(address => uint256) public fees; modifier onlyCreators() { if (msg.sender != creators) { revert Forbidden(); } _; } constructor(address _controller) Controllable(_controller) {} /// @inheritdoc IRaises function create(uint32 projectId, RaiseParams memory params, TierParams[] memory _tiers) external override onlyCreators whenNotPaused returns (uint32 raiseId) { if (!IProjects(projects).exists(projectId)) { revert NotFound(); } params.validate(tokenAuth); raiseId = ++totalRaises[projectId]; // Deploy tokens address fanToken = ITokenDeployer(deployer).deploy(); address brandToken = ITokenDeployer(deployer).deploy(); _saveRaise(projectId, raiseId, fanToken, brandToken, feeSchedule, params); _saveTiers(projectId, raiseId, fanToken, brandToken, _tiers); emit CreateRaise(projectId, raiseId, params, _tiers, fanToken, brandToken); } /// @inheritdoc IRaises function update(uint32 projectId, uint32 raiseId, RaiseParams memory params, TierParams[] memory _tiers) external override onlyCreators whenNotPaused { // Checks Raise storage raise = _getRaise(projectId, raiseId); // Check that raise status is active if (raise.state != RaiseState.Active) revert RaiseInactive(); // Check that raise has not started if (block.timestamp >= raise.timestamps.presaleStart) revert RaiseHasStarted(); params.validate(tokenAuth); address fanToken = raise.tokens.fanToken; address brandToken = raise.tokens.brandToken; _saveRaise(projectId, raiseId, fanToken, brandToken, raise.feeSchedule, params); _saveTiers(projectId, raiseId, fanToken, brandToken, _tiers); emit UpdateRaise(projectId, raiseId, params, _tiers); } /// @inheritdoc IRaises function mint(uint32 projectId, uint32 raiseId, uint32 tierId, uint256 amount) external payable override nonReentrant whenNotPaused returns (uint256 tokenId) { return _mint(projectId, raiseId, tierId, amount, new bytes32[](0)); } /// @inheritdoc IRaises function mint(uint32 projectId, uint32 raiseId, uint32 tierId, uint256 amount, bytes32[] memory proof) external payable override nonReentrant whenNotPaused returns (uint256 tokenId) { return _mint(projectId, raiseId, tierId, amount, proof); } /// @inheritdoc IRaises function settle(uint32 projectId, uint32 raiseId) external override whenNotPaused { // Checks Raise storage raise = _getRaise(projectId, raiseId); // Check that raise status is active if (raise.state != RaiseState.Active) revert RaiseInactive(); // Check that raise has ended if (raise.phase() != Phase.Ended) revert RaiseNotEnded(); // Effects if (raise.raised >= raise.goal) { // If the raise has met its goal, transition to Funded emit SettleRaise(projectId, raiseId, raise.state = RaiseState.Funded); // Add this raise's fees to global fee balance fees[raise.currency] += raise.fees; } else { // Otherwise, transition to Cancelled emit SettleRaise(projectId, raiseId, raise.state = RaiseState.Cancelled); } } /// @inheritdoc IRaises function cancel(uint32 projectId, uint32 raiseId) external override onlyCreators whenNotPaused { // Checks Raise storage raise = _getRaise(projectId, raiseId); if (raise.state != RaiseState.Active) revert RaiseInactive(); // Effects emit CancelRaise(projectId, raiseId, raise.state = RaiseState.Cancelled); } /// @inheritdoc IRaises function close(uint32 projectId, uint32 raiseId) external override onlyCreators whenNotPaused { // Checks Raise storage raise = _getRaise(projectId, raiseId); if (raise.state != RaiseState.Active) revert RaiseInactive(); if (raise.raised < raise.goal) revert RaiseGoalNotMet(); // Effects // Transition to Funded emit CloseRaise(projectId, raiseId, raise.state = RaiseState.Funded); // Add this raise's fees to global fee balance fees[raise.currency] += raise.fees; } /// @inheritdoc IRaises function withdraw(uint32 projectId, uint32 raiseId, address receiver) external override nonReentrant onlyCreators whenNotPaused { // Checks Raise storage raise = _getRaise(projectId, raiseId); // Check that raise has been cancelled if (raise.state != RaiseState.Funded) revert RaiseNotFunded(); // Effects // Store withdrawal amount uint256 amount = raise.balance; // Clear raise balance raise.balance = 0; // Interactions // Get raise currency address currency = raise.currency; if (currency == ETH) { // If currency is ETH, send ETH to receiver payable(receiver).sendValue(amount); } else { // If currency is ERC20, transfer tokens to reciever IERC20(currency).safeTransfer(receiver, amount); } emit WithdrawRaiseFunds(projectId, raiseId, receiver, currency, amount); } /// @inheritdoc IRaises function redeem(uint32 projectId, uint32 raiseId, uint32 tierId, uint256 amount) external override nonReentrant whenNotPaused { // Checks Raise storage raise = _getRaise(projectId, raiseId); // Check that raise has been cancelled if (raise.state != RaiseState.Cancelled) revert RaiseNotCancelled(); // Get the tier if it exists if (tierId >= tiers[projectId][raiseId].length) revert NotFound(); Tier storage tier = tiers[projectId][raiseId][tierId]; // Effects // Calculate refund amount uint256 refund = amount * tier.price; // Calculate protocol fee and creator take (uint256 protocolFee, uint256 creatorTake) = raise.feeSchedule.calculate(tier.tierType, refund); // Deduct refund from balance and fees raise.balance -= Math.min(raise.balance, creatorTake); raise.fees -= protocolFee; // Interactions // Burn token (reverts if caller is not owner or approved) uint256 tokenId = RaiseToken.encode(tier.tierType, projectId, raiseId, tierId); ITokens(tokens).token(tokenId).burn(msg.sender, tokenId, amount); // Get raise currency address currency = raise.currency; if (currency == ETH) { // If currency is ETH, send ETH to caller payable(msg.sender).sendValue(refund); } else { // If currency is ERC20, transfer tokens to caller IERC20(currency).safeTransfer(msg.sender, refund); } emit Redeem(projectId, raiseId, tierId, msg.sender, amount, currency, refund); } /// @inheritdoc IRaises function withdrawFees(address currency, address receiver) external override nonReentrant onlyController { // Checks uint256 balance = fees[currency]; // Revert if fee balance is zero if (balance == 0) revert ZeroBalance(); // Effects // Clear fee balance fees[currency] = 0; // Interactions if (currency == ETH) { // If currency is ETH, send ETH to receiver payable(receiver).sendValue(balance); } else { // If currency is ERC20, transfer tokens to receiver IERC20(currency).safeTransfer(receiver, balance); } emit WithdrawFees(receiver, currency, balance); } function setFeeSchedule(FeeSchedule calldata newFeeSchedule) external override onlyController { newFeeSchedule.validate(); emit SetFeeSchedule(feeSchedule, newFeeSchedule); feeSchedule = newFeeSchedule; } /// @inheritdoc IPausable function pause() external override onlyController { _pause(); } /// @inheritdoc IPausable function unpause() external override onlyController { _unpause(); } /// @inheritdoc IControllable function setDependency(bytes32 _name, address _contract) external override (Controllable, IControllable) onlyController { if (_contract == address(0)) revert ZeroAddress(); else if (_name == "creators") _setCreators(_contract); else if (_name == "projects") _setProjects(_contract); else if (_name == "minter") _setMinter(_contract); else if (_name == "deployer") _setDeployer(_contract); else if (_name == "tokens") _setTokens(_contract); else if (_name == "tokenAuth") _setTokenAuth(_contract); else revert InvalidDependency(_name); } /// @inheritdoc IRaises function getRaise(uint32 projectId, uint32 raiseId) external view override returns (Raise memory) { return _getRaise(projectId, raiseId); } /// @inheritdoc IRaises function getPhase(uint32 projectId, uint32 raiseId) external view override returns (Phase) { return _getRaise(projectId, raiseId).phase(); } /// @inheritdoc IRaises function getTiers(uint32 projectId, uint32 raiseId) external view override returns (Tier[] memory) { // Check that project and raise exist _getRaise(projectId, raiseId); return tiers[projectId][raiseId]; } function _setCreators(address _creators) internal { emit SetCreators(creators, _creators); creators = _creators; } function _setProjects(address _projects) internal { emit SetProjects(projects, _projects); projects = _projects; } function _setMinter(address _minter) internal { emit SetMinter(minter, _minter); minter = _minter; } function _setDeployer(address _deployer) internal { emit SetDeployer(deployer, _deployer); deployer = _deployer; } function _setTokens(address _tokens) internal { emit SetTokens(tokens, _tokens); tokens = _tokens; } function _setTokenAuth(address _tokenAuth) internal { emit SetTokenAuth(tokenAuth, _tokenAuth); tokenAuth = _tokenAuth; } function _getRaise(uint32 projectId, uint32 raiseId) internal view returns (Raise storage raise) { // Check that project exists if (totalRaises[projectId] == 0) revert NotFound(); // Get the raise if it exists raise = raises[projectId][raiseId]; if (raise.projectId == 0) revert NotFound(); } function _mint(uint32 projectId, uint32 raiseId, uint32 tierId, uint256 amount, bytes32[] memory proof) internal returns (uint256 tokenId) { // Checks Raise storage raise = _getRaise(projectId, raiseId); // Check that raise status is active if (raise.state != RaiseState.Active) revert RaiseInactive(); Phase phase = raise.phase(); // Check that raise has started if (phase == Phase.Scheduled) revert RaiseNotStarted(); // Check that raise has not ended if (phase == Phase.Ended) revert RaiseEnded(); // Get the tier if it exists if (tierId >= tiers[projectId][raiseId].length) revert NotFound(); Tier storage tier = tiers[projectId][raiseId][tierId]; // In presale phase, user must provide a valid proof if ( phase == Phase.Presale && !MerkleProof.verify(proof, tier.allowListRoot, keccak256(abi.encodePacked(msg.sender))) ) revert InvalidProof(); // Check that tier has remaining supply if (tier.minted + amount > tier.supply) revert RaiseSoldOut(); // Check that caller will not exceed limit per address if (mints[projectId][raiseId][tierId][msg.sender] + amount > tier.limitPerAddress) { revert AddressMintedMaximum(); } // Calculate mint price. uint256 mintPrice = amount * tier.price; // Get the currency for this raise. Save for use later. address currency = raise.currency; if (currency == ETH) { // If currency is ETH, msg.value must be mintPrice if (msg.value != mintPrice) revert InvalidPaymentAmount(); } else { // If currency is not ETH, msg.value must be zero if (msg.value != 0) revert InvalidPaymentAmount(); // Check that currency has not been removed from the ERC20 allowlist if (ITokenAuth(tokenAuth).denied(currency)) revert InvalidCurrency(); } // Calculate total raised uint256 totalRaised = raise.raised + mintPrice; // If there is a raise maximum, check that payment does not exceed it if (raise.max != 0 && totalRaised > raise.max) revert ExceedsRaiseMaximum(); // Effects // Increment per-caller mint count mints[projectId][raiseId][tierId][msg.sender] += amount; // Increment tier minted count tier.minted += amount; // Increase raised amount raise.raised = totalRaised; // Calculate protocol fee and creator take (uint256 protocolFee, uint256 creatorTake) = raise.feeSchedule.calculate(tier.tierType, mintPrice); // Increase balances raise.balance += creatorTake; raise.fees += protocolFee; // Interactions // If currency is not ETH, transfer tokens from caller if (currency != ETH) { IERC20(currency).safeTransferFrom(msg.sender, address(this), mintPrice); } // Encode token ID tokenId = RaiseToken.encode(tier.tierType, projectId, raiseId, tierId); // Mint token to caller IMinter(minter).mint(msg.sender, tokenId, amount, ""); // Emit event emit Mint(projectId, raiseId, tierId, msg.sender, amount, proof); } function _saveRaise( uint32 projectId, uint32 raiseId, address fanToken, address brandToken, FeeSchedule memory _feeSchedule, RaiseParams memory params ) internal { raises[projectId][raiseId] = Raise({ currency: params.currency, goal: params.goal, max: params.max, timestamps: RaiseTimestamps({ presaleStart: params.presaleStart, presaleEnd: params.presaleEnd, publicSaleStart: params.publicSaleStart, publicSaleEnd: params.publicSaleEnd }), state: RaiseState.Active, projectId: projectId, raiseId: raiseId, tokens: RaiseTokens({fanToken: fanToken, brandToken: brandToken}), feeSchedule: _feeSchedule, raised: 0, balance: 0, fees: 0 }); } function _saveTiers( uint32 projectId, uint32 raiseId, address fanToken, address brandToken, TierParams[] memory _tiers ) internal { delete tiers[projectId][raiseId]; for (uint256 i; i < _tiers.length;) { TierParams memory tierParams = _tiers[i]; tierParams.validate(); tiers[projectId][raiseId].push( Tier({ tierType: tierParams.tierType, price: tierParams.price, supply: tierParams.supply, limitPerAddress: tierParams.limitPerAddress, allowListRoot: tierParams.allowListRoot, minted: 0 }) ); // Register token uint256 tokenId = RaiseToken.encode(tierParams.tierType, projectId, raiseId, uint32(i)); address token = tierParams.tierType == TierType.Fan ? fanToken : brandToken; ITokenDeployer(deployer).register(tokenId, token); unchecked { ++i; } } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (security/Pausable.sol) pragma solidity ^0.8.0; import "../utils/Context.sol"; /** * @dev Contract module which allows children to implement an emergency stop * mechanism that can be triggered by an authorized account. * * This module is used through inheritance. It will make available the * modifiers `whenNotPaused` and `whenPaused`, which can be applied to * the functions of your contract. Note that they will not be pausable by * simply including this module, only once the modifiers are put in place. */ abstract contract Pausable is Context { /** * @dev Emitted when the pause is triggered by `account`. */ event Paused(address account); /** * @dev Emitted when the pause is lifted by `account`. */ event Unpaused(address account); bool private _paused; /** * @dev Initializes the contract in unpaused state. */ constructor() { _paused = false; } /** * @dev Modifier to make a function callable only when the contract is not paused. * * Requirements: * * - The contract must not be paused. */ modifier whenNotPaused() { _requireNotPaused(); _; } /** * @dev Modifier to make a function callable only when the contract is paused. * * Requirements: * * - The contract must be paused. */ modifier whenPaused() { _requirePaused(); _; } /** * @dev Returns true if the contract is paused, and false otherwise. */ function paused() public view virtual returns (bool) { return _paused; } /** * @dev Throws if the contract is paused. */ function _requireNotPaused() internal view virtual { require(!paused(), "Pausable: paused"); } /** * @dev Throws if the contract is not paused. */ function _requirePaused() internal view virtual { require(paused(), "Pausable: not paused"); } /** * @dev Triggers stopped state. * * Requirements: * * - The contract must not be paused. */ function _pause() internal virtual whenNotPaused { _paused = true; emit Paused(_msgSender()); } /** * @dev Returns to normal state. * * Requirements: * * - The contract must be paused. */ function _unpause() internal virtual whenPaused { _paused = false; emit Unpaused(_msgSender()); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (security/ReentrancyGuard.sol) pragma solidity ^0.8.0; /** * @dev Contract module that helps prevent reentrant calls to a function. * * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier * available, which can be applied to functions to make sure there are no nested * (reentrant) calls to them. * * Note that because there is a single `nonReentrant` guard, functions marked as * `nonReentrant` may not call one another. This can be worked around by making * those functions `private`, and then adding `external` `nonReentrant` entry * points to them. * * TIP: If you would like to learn more about reentrancy and alternative ways * to protect against it, check out our blog post * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul]. */ abstract contract ReentrancyGuard { // Booleans are more expensive than uint256 or any type that takes up a full // word because each write operation emits an extra SLOAD to first read the // slot's contents, replace the bits taken up by the boolean, and then write // back. This is the compiler's defense against contract upgrades and // pointer aliasing, and it cannot be disabled. // The values being non-zero value makes deployment a bit more expensive, // but in exchange the refund on every call to nonReentrant will be lower in // amount. Since refunds are capped to a percentage of the total // transaction's gas, it is best to keep them low in cases like this one, to // increase the likelihood of the full refund coming into effect. uint256 private constant _NOT_ENTERED = 1; uint256 private constant _ENTERED = 2; uint256 private _status; constructor() { _status = _NOT_ENTERED; } /** * @dev Prevents a contract from calling itself, directly or indirectly. * Calling a `nonReentrant` function from another `nonReentrant` * function is not supported. It is possible to prevent this from happening * by making the `nonReentrant` function external, and making it call a * `private` function that does the actual work. */ modifier nonReentrant() { _nonReentrantBefore(); _; _nonReentrantAfter(); } function _nonReentrantBefore() private { // On the first call to nonReentrant, _status will be _NOT_ENTERED require(_status != _ENTERED, "ReentrancyGuard: reentrant call"); // Any calls to nonReentrant after this point will fail _status = _ENTERED; } function _nonReentrantAfter() private { // By storing the original value once again, a refund is triggered (see // https://eips.ethereum.org/EIPS/eip-2200) _status = _NOT_ENTERED; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `to`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address to, uint256 amount) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 amount) external returns (bool); /** * @dev Moves `amount` tokens from `from` to `to` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom( address from, address to, uint256 amount ) external returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-IERC20Permit.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612]. * * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't * need to send a transaction, and thus is not required to hold Ether at all. */ interface IERC20Permit { /** * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens, * given ``owner``'s signed approval. * * IMPORTANT: The same issues {IERC20-approve} has related to transaction * ordering also apply here. * * Emits an {Approval} event. * * Requirements: * * - `spender` cannot be the zero address. * - `deadline` must be a timestamp in the future. * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner` * over the EIP712-formatted function arguments. * - the signature must use ``owner``'s current nonce (see {nonces}). * * For more information on the signature format, see the * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP * section]. */ function permit( address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) external; /** * @dev Returns the current nonce for `owner`. This value must be * included whenever a signature is generated for {permit}. * * Every successful call to {permit} increases ``owner``'s nonce by one. This * prevents a signature from being used multiple times. */ function nonces(address owner) external view returns (uint256); /** * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}. */ // solhint-disable-next-line func-name-mixedcase function DOMAIN_SEPARATOR() external view returns (bytes32); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/utils/SafeERC20.sol) pragma solidity ^0.8.0; import "../IERC20.sol"; import "../extensions/draft-IERC20Permit.sol"; import "../../../utils/Address.sol"; /** * @title SafeERC20 * @dev Wrappers around ERC20 operations that throw on failure (when the token * contract returns false). Tokens that return no value (and instead revert or * throw on failure) are also supported, non-reverting calls are assumed to be * successful. * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract, * which allows you to call the safe operations as `token.safeTransfer(...)`, etc. */ library SafeERC20 { using Address for address; function safeTransfer( IERC20 token, address to, uint256 value ) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value)); } function safeTransferFrom( IERC20 token, address from, address to, uint256 value ) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value)); } /** * @dev Deprecated. This function has issues similar to the ones found in * {IERC20-approve}, and its usage is discouraged. * * Whenever possible, use {safeIncreaseAllowance} and * {safeDecreaseAllowance} instead. */ function safeApprove( IERC20 token, address spender, uint256 value ) internal { // safeApprove should only be called when setting an initial allowance, // or when resetting it to zero. To increase and decrease it, use // 'safeIncreaseAllowance' and 'safeDecreaseAllowance' require( (value == 0) || (token.allowance(address(this), spender) == 0), "SafeERC20: approve from non-zero to non-zero allowance" ); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value)); } function safeIncreaseAllowance( IERC20 token, address spender, uint256 value ) internal { uint256 newAllowance = token.allowance(address(this), spender) + value; _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } function safeDecreaseAllowance( IERC20 token, address spender, uint256 value ) internal { unchecked { uint256 oldAllowance = token.allowance(address(this), spender); require(oldAllowance >= value, "SafeERC20: decreased allowance below zero"); uint256 newAllowance = oldAllowance - value; _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } } function safePermit( IERC20Permit token, address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) internal { uint256 nonceBefore = token.nonces(owner); token.permit(owner, spender, value, deadline, v, r, s); uint256 nonceAfter = token.nonces(owner); require(nonceAfter == nonceBefore + 1, "SafeERC20: permit did not succeed"); } /** * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement * on the return value: the return value is optional (but if data is returned, it must not be false). * @param token The token targeted by the call. * @param data The call data (encoded using abi.encode or one of its variants). */ function _callOptionalReturn(IERC20 token, bytes memory data) private { // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since // we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that // the target address contains contract code and also asserts for success in the low-level call. bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed"); if (returndata.length > 0) { // Return data is optional require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed"); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol) pragma solidity ^0.8.1; /** * @dev Collection of functions related to the address type */ library Address { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * ==== * * [IMPORTANT] * ==== * You shouldn't rely on `isContract` to protect against flash loan attacks! * * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract * constructor. * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize/address.code.length, which returns 0 // for contracts in construction, since the code is only stored at the end // of the constructor execution. return account.code.length > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); (bool success, ) = recipient.call{value: amount}(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value ) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value, string memory errorMessage ) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall( address target, bytes memory data, string memory errorMessage ) internal view returns (bytes memory) { (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { return functionDelegateCall(target, data, "Address: low-level delegate call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract. * * _Available since v4.8._ */ function verifyCallResultFromTarget( address target, bool success, bytes memory returndata, string memory errorMessage ) internal view returns (bytes memory) { if (success) { if (returndata.length == 0) { // only check isContract if the call was successful and the return data is empty // otherwise we already know that it was a contract require(isContract(target), "Address: call to non-contract"); } return returndata; } else { _revert(returndata, errorMessage); } } /** * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason or using the provided one. * * _Available since v4.3._ */ function verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) internal pure returns (bytes memory) { if (success) { return returndata; } else { _revert(returndata, errorMessage); } } function _revert(bytes memory returndata, string memory errorMessage) private pure { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly /// @solidity memory-safe-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/Context.sol) pragma solidity ^0.8.0; /** * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract Context { function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (utils/cryptography/MerkleProof.sol) pragma solidity ^0.8.0; /** * @dev These functions deal with verification of Merkle Tree proofs. * * The proofs can be generated using the JavaScript library * https://github.com/miguelmota/merkletreejs[merkletreejs]. * Note: the hashing algorithm should be keccak256 and pair sorting should be enabled. * * See `test/utils/cryptography/MerkleProof.test.js` for some examples. * * WARNING: You should avoid using leaf values that are 64 bytes long prior to * hashing, or use a hash function other than keccak256 for hashing leaves. * This is because the concatenation of a sorted pair of internal nodes in * the merkle tree could be reinterpreted as a leaf value. */ library MerkleProof { /** * @dev Returns true if a `leaf` can be proved to be a part of a Merkle tree * defined by `root`. For this, a `proof` must be provided, containing * sibling hashes on the branch from the leaf to the root of the tree. Each * pair of leaves and each pair of pre-images are assumed to be sorted. */ function verify( bytes32[] memory proof, bytes32 root, bytes32 leaf ) internal pure returns (bool) { return processProof(proof, leaf) == root; } /** * @dev Calldata version of {verify} * * _Available since v4.7._ */ function verifyCalldata( bytes32[] calldata proof, bytes32 root, bytes32 leaf ) internal pure returns (bool) { return processProofCalldata(proof, leaf) == root; } /** * @dev Returns the rebuilt hash obtained by traversing a Merkle tree up * from `leaf` using `proof`. A `proof` is valid if and only if the rebuilt * hash matches the root of the tree. When processing the proof, the pairs * of leafs & pre-images are assumed to be sorted. * * _Available since v4.4._ */ function processProof(bytes32[] memory proof, bytes32 leaf) internal pure returns (bytes32) { bytes32 computedHash = leaf; for (uint256 i = 0; i < proof.length; i++) { computedHash = _hashPair(computedHash, proof[i]); } return computedHash; } /** * @dev Calldata version of {processProof} * * _Available since v4.7._ */ function processProofCalldata(bytes32[] calldata proof, bytes32 leaf) internal pure returns (bytes32) { bytes32 computedHash = leaf; for (uint256 i = 0; i < proof.length; i++) { computedHash = _hashPair(computedHash, proof[i]); } return computedHash; } /** * @dev Returns true if the `leaves` can be proved to be a part of a Merkle tree defined by * `root`, according to `proof` and `proofFlags` as described in {processMultiProof}. * * _Available since v4.7._ */ function multiProofVerify( bytes32[] memory proof, bool[] memory proofFlags, bytes32 root, bytes32[] memory leaves ) internal pure returns (bool) { return processMultiProof(proof, proofFlags, leaves) == root; } /** * @dev Calldata version of {multiProofVerify} * * _Available since v4.7._ */ function multiProofVerifyCalldata( bytes32[] calldata proof, bool[] calldata proofFlags, bytes32 root, bytes32[] memory leaves ) internal pure returns (bool) { return processMultiProofCalldata(proof, proofFlags, leaves) == root; } /** * @dev Returns the root of a tree reconstructed from `leaves` and the sibling nodes in `proof`, * consuming from one or the other at each step according to the instructions given by * `proofFlags`. * * _Available since v4.7._ */ function processMultiProof( bytes32[] memory proof, bool[] memory proofFlags, bytes32[] memory leaves ) internal pure returns (bytes32 merkleRoot) { // This function rebuild the root hash by traversing the tree up from the leaves. The root is rebuilt by // consuming and producing values on a queue. The queue starts with the `leaves` array, then goes onto the // `hashes` array. At the end of the process, the last hash in the `hashes` array should contain the root of // the merkle tree. uint256 leavesLen = leaves.length; uint256 totalHashes = proofFlags.length; // Check proof validity. require(leavesLen + proof.length - 1 == totalHashes, "MerkleProof: invalid multiproof"); // The xxxPos values are "pointers" to the next value to consume in each array. All accesses are done using // `xxx[xxxPos++]`, which return the current value and increment the pointer, thus mimicking a queue's "pop". bytes32[] memory hashes = new bytes32[](totalHashes); uint256 leafPos = 0; uint256 hashPos = 0; uint256 proofPos = 0; // At each step, we compute the next hash using two values: // - a value from the "main queue". If not all leaves have been consumed, we get the next leaf, otherwise we // get the next hash. // - depending on the flag, either another value for the "main queue" (merging branches) or an element from the // `proof` array. for (uint256 i = 0; i < totalHashes; i++) { bytes32 a = leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++]; bytes32 b = proofFlags[i] ? leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++] : proof[proofPos++]; hashes[i] = _hashPair(a, b); } if (totalHashes > 0) { return hashes[totalHashes - 1]; } else if (leavesLen > 0) { return leaves[0]; } else { return proof[0]; } } /** * @dev Calldata version of {processMultiProof} * * _Available since v4.7._ */ function processMultiProofCalldata( bytes32[] calldata proof, bool[] calldata proofFlags, bytes32[] memory leaves ) internal pure returns (bytes32 merkleRoot) { // This function rebuild the root hash by traversing the tree up from the leaves. The root is rebuilt by // consuming and producing values on a queue. The queue starts with the `leaves` array, then goes onto the // `hashes` array. At the end of the process, the last hash in the `hashes` array should contain the root of // the merkle tree. uint256 leavesLen = leaves.length; uint256 totalHashes = proofFlags.length; // Check proof validity. require(leavesLen + proof.length - 1 == totalHashes, "MerkleProof: invalid multiproof"); // The xxxPos values are "pointers" to the next value to consume in each array. All accesses are done using // `xxx[xxxPos++]`, which return the current value and increment the pointer, thus mimicking a queue's "pop". bytes32[] memory hashes = new bytes32[](totalHashes); uint256 leafPos = 0; uint256 hashPos = 0; uint256 proofPos = 0; // At each step, we compute the next hash using two values: // - a value from the "main queue". If not all leaves have been consumed, we get the next leaf, otherwise we // get the next hash. // - depending on the flag, either another value for the "main queue" (merging branches) or an element from the // `proof` array. for (uint256 i = 0; i < totalHashes; i++) { bytes32 a = leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++]; bytes32 b = proofFlags[i] ? leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++] : proof[proofPos++]; hashes[i] = _hashPair(a, b); } if (totalHashes > 0) { return hashes[totalHashes - 1]; } else if (leavesLen > 0) { return leaves[0]; } else { return proof[0]; } } function _hashPair(bytes32 a, bytes32 b) private pure returns (bytes32) { return a < b ? _efficientHash(a, b) : _efficientHash(b, a); } function _efficientHash(bytes32 a, bytes32 b) private pure returns (bytes32 value) { /// @solidity memory-safe-assembly assembly { mstore(0x00, a) mstore(0x20, b) value := keccak256(0x00, 0x40) } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (utils/math/Math.sol) pragma solidity ^0.8.0; /** * @dev Standard math utilities missing in the Solidity language. */ library Math { enum Rounding { Down, // Toward negative infinity Up, // Toward infinity Zero // Toward zero } /** * @dev Returns the largest of two numbers. */ function max(uint256 a, uint256 b) internal pure returns (uint256) { return a > b ? a : b; } /** * @dev Returns the smallest of two numbers. */ function min(uint256 a, uint256 b) internal pure returns (uint256) { return a < b ? a : b; } /** * @dev Returns the average of two numbers. The result is rounded towards * zero. */ function average(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b) / 2 can overflow. return (a & b) + (a ^ b) / 2; } /** * @dev Returns the ceiling of the division of two numbers. * * This differs from standard division with `/` in that it rounds up instead * of rounding down. */ function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b - 1) / b can overflow on addition, so we distribute. return a == 0 ? 0 : (a - 1) / b + 1; } /** * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0 * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv) * with further edits by Uniswap Labs also under MIT license. */ function mulDiv( uint256 x, uint256 y, uint256 denominator ) internal pure returns (uint256 result) { unchecked { // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256 // variables such that product = prod1 * 2^256 + prod0. uint256 prod0; // Least significant 256 bits of the product uint256 prod1; // Most significant 256 bits of the product assembly { let mm := mulmod(x, y, not(0)) prod0 := mul(x, y) prod1 := sub(sub(mm, prod0), lt(mm, prod0)) } // Handle non-overflow cases, 256 by 256 division. if (prod1 == 0) { return prod0 / denominator; } // Make sure the result is less than 2^256. Also prevents denominator == 0. require(denominator > prod1); /////////////////////////////////////////////// // 512 by 256 division. /////////////////////////////////////////////// // Make division exact by subtracting the remainder from [prod1 prod0]. uint256 remainder; assembly { // Compute remainder using mulmod. remainder := mulmod(x, y, denominator) // Subtract 256 bit number from 512 bit number. prod1 := sub(prod1, gt(remainder, prod0)) prod0 := sub(prod0, remainder) } // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1. // See https://cs.stackexchange.com/q/138556/92363. // Does not overflow because the denominator cannot be zero at this stage in the function. uint256 twos = denominator & (~denominator + 1); assembly { // Divide denominator by twos. denominator := div(denominator, twos) // Divide [prod1 prod0] by twos. prod0 := div(prod0, twos) // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one. twos := add(div(sub(0, twos), twos), 1) } // Shift in bits from prod1 into prod0. prod0 |= prod1 * twos; // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for // four bits. That is, denominator * inv = 1 mod 2^4. uint256 inverse = (3 * denominator) ^ 2; // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works // in modular arithmetic, doubling the correct bits in each step. inverse *= 2 - denominator * inverse; // inverse mod 2^8 inverse *= 2 - denominator * inverse; // inverse mod 2^16 inverse *= 2 - denominator * inverse; // inverse mod 2^32 inverse *= 2 - denominator * inverse; // inverse mod 2^64 inverse *= 2 - denominator * inverse; // inverse mod 2^128 inverse *= 2 - denominator * inverse; // inverse mod 2^256 // Because the division is now exact we can divide by multiplying with the modular inverse of denominator. // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1 // is no longer required. result = prod0 * inverse; return result; } } /** * @notice Calculates x * y / denominator with full precision, following the selected rounding direction. */ function mulDiv( uint256 x, uint256 y, uint256 denominator, Rounding rounding ) internal pure returns (uint256) { uint256 result = mulDiv(x, y, denominator); if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) { result += 1; } return result; } /** * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down. * * Inspired by Henry S. Warren, Jr.'s "Hacker's Delight" (Chapter 11). */ function sqrt(uint256 a) internal pure returns (uint256) { if (a == 0) { return 0; } // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target. // // We know that the "msb" (most significant bit) of our target number `a` is a power of 2 such that we have // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`. // // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)` // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))` // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)` // // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit. uint256 result = 1 << (log2(a) >> 1); // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128, // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision // into the expected uint128 result. unchecked { result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; return min(result, a / result); } } /** * @notice Calculates sqrt(a), following the selected rounding direction. */ function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = sqrt(a); return result + (rounding == Rounding.Up && result * result < a ? 1 : 0); } } /** * @dev Return the log in base 2, rounded down, of a positive value. * Returns 0 if given 0. */ function log2(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >> 128 > 0) { value >>= 128; result += 128; } if (value >> 64 > 0) { value >>= 64; result += 64; } if (value >> 32 > 0) { value >>= 32; result += 32; } if (value >> 16 > 0) { value >>= 16; result += 16; } if (value >> 8 > 0) { value >>= 8; result += 8; } if (value >> 4 > 0) { value >>= 4; result += 4; } if (value >> 2 > 0) { value >>= 2; result += 2; } if (value >> 1 > 0) { result += 1; } } return result; } /** * @dev Return the log in base 2, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log2(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log2(value); return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0); } } /** * @dev Return the log in base 10, rounded down, of a positive value. * Returns 0 if given 0. */ function log10(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >= 10**64) { value /= 10**64; result += 64; } if (value >= 10**32) { value /= 10**32; result += 32; } if (value >= 10**16) { value /= 10**16; result += 16; } if (value >= 10**8) { value /= 10**8; result += 8; } if (value >= 10**4) { value /= 10**4; result += 4; } if (value >= 10**2) { value /= 10**2; result += 2; } if (value >= 10**1) { result += 1; } } return result; } /** * @dev Return the log in base 10, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log10(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log10(value); return result + (rounding == Rounding.Up && 10**result < value ? 1 : 0); } } /** * @dev Return the log in base 256, rounded down, of a positive value. * Returns 0 if given 0. * * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string. */ function log256(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >> 128 > 0) { value >>= 128; result += 16; } if (value >> 64 > 0) { value >>= 64; result += 8; } if (value >> 32 > 0) { value >>= 32; result += 4; } if (value >> 16 > 0) { value >>= 16; result += 2; } if (value >> 8 > 0) { result += 1; } } return result; } /** * @dev Return the log in base 10, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log256(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log256(value); return result + (rounding == Rounding.Up && 1 << (result * 8) < value ? 1 : 0); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.6.0) (interfaces/IERC2981.sol) pragma solidity ^0.8.0; import "../utils/introspection/IERC165Upgradeable.sol"; /** * @dev Interface for the NFT Royalty Standard. * * A standardized way to retrieve royalty payment information for non-fungible tokens (NFTs) to enable universal * support for royalty payments across all NFT marketplaces and ecosystem participants. * * _Available since v4.5._ */ interface IERC2981Upgradeable is IERC165Upgradeable { /** * @dev Returns how much royalty is owed and to whom, based on a sale price that may be denominated in any unit of * exchange. The royalty amount is denominated and should be paid in that same unit of exchange. */ function royaltyInfo(uint256 tokenId, uint256 salePrice) external view returns (address receiver, uint256 royaltyAmount); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (token/ERC1155/IERC1155.sol) pragma solidity ^0.8.0; import "../../utils/introspection/IERC165Upgradeable.sol"; /** * @dev Required interface of an ERC1155 compliant contract, as defined in the * https://eips.ethereum.org/EIPS/eip-1155[EIP]. * * _Available since v3.1._ */ interface IERC1155Upgradeable is IERC165Upgradeable { /** * @dev Emitted when `value` tokens of token type `id` are transferred from `from` to `to` by `operator`. */ event TransferSingle(address indexed operator, address indexed from, address indexed to, uint256 id, uint256 value); /** * @dev Equivalent to multiple {TransferSingle} events, where `operator`, `from` and `to` are the same for all * transfers. */ event TransferBatch( address indexed operator, address indexed from, address indexed to, uint256[] ids, uint256[] values ); /** * @dev Emitted when `account` grants or revokes permission to `operator` to transfer their tokens, according to * `approved`. */ event ApprovalForAll(address indexed account, address indexed operator, bool approved); /** * @dev Emitted when the URI for token type `id` changes to `value`, if it is a non-programmatic URI. * * If an {URI} event was emitted for `id`, the standard * https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[guarantees] that `value` will equal the value * returned by {IERC1155MetadataURI-uri}. */ event URI(string value, uint256 indexed id); /** * @dev Returns the amount of tokens of token type `id` owned by `account`. * * Requirements: * * - `account` cannot be the zero address. */ function balanceOf(address account, uint256 id) external view returns (uint256); /** * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {balanceOf}. * * Requirements: * * - `accounts` and `ids` must have the same length. */ function balanceOfBatch(address[] calldata accounts, uint256[] calldata ids) external view returns (uint256[] memory); /** * @dev Grants or revokes permission to `operator` to transfer the caller's tokens, according to `approved`, * * Emits an {ApprovalForAll} event. * * Requirements: * * - `operator` cannot be the caller. */ function setApprovalForAll(address operator, bool approved) external; /** * @dev Returns true if `operator` is approved to transfer ``account``'s tokens. * * See {setApprovalForAll}. */ function isApprovedForAll(address account, address operator) external view returns (bool); /** * @dev Transfers `amount` tokens of token type `id` from `from` to `to`. * * Emits a {TransferSingle} event. * * Requirements: * * - `to` cannot be the zero address. * - If the caller is not `from`, it must have been approved to spend ``from``'s tokens via {setApprovalForAll}. * - `from` must have a balance of tokens of type `id` of at least `amount`. * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the * acceptance magic value. */ function safeTransferFrom( address from, address to, uint256 id, uint256 amount, bytes calldata data ) external; /** * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {safeTransferFrom}. * * Emits a {TransferBatch} event. * * Requirements: * * - `ids` and `amounts` must have the same length. * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the * acceptance magic value. */ function safeBatchTransferFrom( address from, address to, uint256[] calldata ids, uint256[] calldata amounts, bytes calldata data ) external; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (token/ERC1155/extensions/IERC1155MetadataURI.sol) pragma solidity ^0.8.0; import "../IERC1155Upgradeable.sol"; /** * @dev Interface of the optional ERC1155MetadataExtension interface, as defined * in the https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[EIP]. * * _Available since v3.1._ */ interface IERC1155MetadataURIUpgradeable is IERC1155Upgradeable { /** * @dev Returns the URI for token type `id`. * * If the `\{id\}` substring is present in the URI, it must be replaced by * clients with the actual token type ID. */ function uri(uint256 id) external view returns (string memory); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC165 standard, as defined in the * https://eips.ethereum.org/EIPS/eip-165[EIP]. * * Implementers can declare support of contract interfaces, which can then be * queried by others ({ERC165Checker}). * * For an implementation, see {ERC165}. */ interface IERC165Upgradeable { /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] * to learn more about how these ids are created. * * This function call must use less than 30 000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); }
// SPDX-License-Identifier: MIT pragma solidity 0.8.17; import {IControllable} from "../interfaces/IControllable.sol"; /// @title Controllable - Controller management functions /// @notice An abstract base contract for contracts managed by the Controller. abstract contract Controllable is IControllable { address public controller; modifier onlyController() { if (msg.sender != controller) { revert Forbidden(); } _; } constructor(address _controller) { if (_controller == address(0)) { revert ZeroAddress(); } controller = _controller; } /// @inheritdoc IControllable function setDependency(bytes32 _name, address) external virtual onlyController { revert InvalidDependency(_name); } }
// SPDX-License-Identifier: MIT pragma solidity 0.8.17; import {Pausable as OZPausable} from "openzeppelin-contracts/security/Pausable.sol"; import {IPausable} from "../interfaces/IPausable.sol"; /// @title Pausable - Pause and unpause functionality /// @notice Wraps OZ Pausable and adds an IPausable interface. abstract contract Pausable is IPausable, OZPausable {}
// SPDX-License-Identifier: MIT pragma solidity 0.8.17; uint256 constant ONE_BYTE = 0x8; uint256 constant ONE_BYTE_MASK = type(uint8).max; uint256 constant TWO_BYTES = 0x10; uint256 constant FOUR_BYTES = 0x20; uint256 constant FOUR_BYTE_MASK = type(uint32).max; uint256 constant THIRTY_BYTES = 0xf0; uint256 constant THIRTY_BYTE_MASK = type(uint240).max;
// SPDX-License-Identifier: MIT pragma solidity 0.8.17; /// @dev The "dolphin address," a special value representing native ETH. address constant ETH = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;
// SPDX-License-Identifier: MIT pragma solidity 0.8.17; import {IControllable} from "./IControllable.sol"; interface IAllowList is IControllable { event Allow(address caller); event Deny(address caller); /// @notice Check whether the given `caller` address is allowed. /// @param caller The caller address. /// @return True if caller is allowed, false if caller is denied. function allowed(address caller) external view returns (bool); /// @notice Check whether the given `caller` address is denied. /// @param caller The caller address. /// @return True if caller is denied, false if caller is allowed. function denied(address caller) external view returns (bool); /// @notice Add a caller address to the allowlist. /// @param caller The caller address. function allow(address caller) external; /// @notice Remove a caller address from the allowlist. /// @param caller The caller address. function deny(address caller) external; }
// SPDX-License-Identifier: MIT pragma solidity 0.8.17; interface IAnnotated { /// @notice Get contract name. /// @return Contract name. function NAME() external returns (string memory); /// @notice Get contract version. /// @return Contract version. function VERSION() external returns (string memory); }
// SPDX-License-Identifier: MIT pragma solidity 0.8.17; interface ICommonErrors { /// @notice The provided address is the zero address. error ZeroAddress(); /// @notice The attempted action is not allowed. error Forbidden(); /// @notice The requested entity cannot be found. error NotFound(); }
// SPDX-License-Identifier: MIT pragma solidity 0.8.17; import {ICommonErrors} from "./ICommonErrors.sol"; interface IControllable is ICommonErrors { /// @notice The dependency with the given `name` is invalid. error InvalidDependency(bytes32 name); /// @notice Get controller address. /// @return Controller address. function controller() external returns (address); /// @notice Set a named dependency to the given contract address. /// @param _name bytes32 name of the dependency to set. /// @param _contract address of the dependency. function setDependency(bytes32 _name, address _contract) external; }
// SPDX-License-Identifier: MIT pragma solidity 0.8.17; import {IERC1155MetadataURIUpgradeable} from "openzeppelin-contracts-upgradeable/token/ERC1155/extensions/IERC1155MetadataURIUpgradeable.sol"; import {IERC2981Upgradeable} from "openzeppelin-contracts-upgradeable/interfaces/IERC2981Upgradeable.sol"; import {IAnnotated} from "./IAnnotated.sol"; import {ICommonErrors} from "./ICommonErrors.sol"; interface IEmint1155 is IERC1155MetadataURIUpgradeable, IERC2981Upgradeable, IAnnotated, ICommonErrors { /// @notice Initialize the cloned Emint1155 token contract. /// @param tokens address of tokens module. function initialize(address tokens) external; /// @notice Get address of metadata module. /// @return address of metadata module. function metadata() external view returns (address); /// @notice Get address of royalties module. /// @return address of royalties module. function royalties() external view returns (address); /// @notice Get address of collection owner. This address has no special /// permissions at the contract level, but will be authorized to manage this /// token's collection on storefronts like OpenSea. /// @return address of collection owner. function owner() external view returns (address); /// @notice Get contract metadata URI. Used by marketplaces like OpenSea to /// retrieve information about the token contract/collection. /// @return URI of contract metadata. function contractURI() external view returns (string memory); /// @notice Mint `amount` tokens with ID `id` to `to` address, passing `data`. /// @param to address of token reciever. /// @param id uint256 token ID. /// @param amount uint256 quantity of tokens to mint. /// @param data bytes of data to pass to ERC1155 mint function. function mint(address to, uint256 id, uint256 amount, bytes memory data) external; /// @notice Batch mint tokens to `to` address, passing `data`. /// @param to address of token reciever. /// @param ids uint256[] array of token IDs. /// @param amounts uint256[] array of quantities to mint. /// @param data bytes of data to pass to ERC1155 mint function. function mintBatch(address to, uint256[] memory ids, uint256[] memory amounts, bytes memory data) external; /// @notice Burn `amount` of tokens with ID `id` from `account` /// @param account address of token owner. /// @param id uint256 token ID. /// @param amount uint256 quantity of tokens to mint. function burn(address account, uint256 id, uint256 amount) external; /// @notice Batch burn tokens from `account` address. /// @param account address of token owner. /// @param ids uint256[] array of token IDs. /// @param amounts uint256[] array of quantities to burn. function burnBatch(address account, uint256[] memory ids, uint256[] memory amounts) external; }
// SPDX-License-Identifier: MIT pragma solidity 0.8.17; import {IAllowList} from "./IAllowList.sol"; import {IAnnotated} from "./IAnnotated.sol"; interface IMinter is IAllowList, IAnnotated { event SetTokens(address oldTokens, address newTokens); /// @notice Mint `amount` tokens with ID `id` to `to` address, passing `data`. /// @param to address of token reciever. /// @param id uint256 token ID. /// @param amount uint256 quantity of tokens to mint. /// @param data bytes of data to pass to ERC1155 mint function. function mint(address to, uint256 id, uint256 amount, bytes memory data) external; }
// SPDX-License-Identifier: MIT pragma solidity 0.8.17; interface IPausable { /// @notice Pause the contract. function pause() external; /// @notice Unpause the contract. function unpause() external; }
// SPDX-License-Identifier: MIT pragma solidity 0.8.17; import {IAnnotated} from "./IAnnotated.sol"; import {ICommonErrors} from "./ICommonErrors.sol"; import {IPausable} from "./IPausable.sol"; import {IAllowList} from "./IAllowList.sol"; interface IProjects is IAllowList, IPausable, IAnnotated { event CreateProject(uint32 id); event TransferOwnership(uint32 indexed projectId, address indexed owner, address indexed newOwner); event AcceptOwnership(uint32 indexed projectId, address indexed owner, address indexed newOwner); /// @notice Create a new project owned by the given `owner`. /// @param owner address of project owner. /// @return uint32 Project ID. function create(address owner) external returns (uint32); /// @notice Start transfer of `projectId` to `newOwner`. The new owner must /// accept the transfer in order to assume ownership of the project. /// @param projectId uint32 project ID. /// @param newOwner address of proposed new owner. function transferOwnership(uint32 projectId, address newOwner) external; /// @notice Transfer ownership of `projectId` to `pendingOwner`. /// @param projectId uint32 project ID. function acceptOwnership(uint32 projectId) external; /// @notice Get owner of project by ID. /// @param projectId uint32 project ID. /// @return address of project owner. function ownerOf(uint32 projectId) external view returns (address); /// @notice Get pending owner of project by ID. /// @param projectId uint32 project ID. /// @return address of pending project owner. function pendingOwnerOf(uint32 projectId) external view returns (address); /// @notice Check whether project exists by ID. /// @param projectId uint32 project ID. /// @return True if project exists, false if project does not exist. function exists(uint32 projectId) external view returns (bool); }
// SPDX-License-Identifier: MIT pragma solidity 0.8.17; import {IControllable} from "./IControllable.sol"; import {IAnnotated} from "./IAnnotated.sol"; import {IPausable} from "./IPausable.sol"; import {Raise, RaiseParams, RaiseState, Phase, FeeSchedule} from "../structs/Raise.sol"; import {Tier, TierParams} from "../structs/Tier.sol"; interface IRaises is IPausable, IControllable, IAnnotated { /// @notice Minting token would exceed the raise's configured maximum amount. error ExceedsRaiseMaximum(); /// @notice The raise's goal has not been met. error RaiseGoalNotMet(); /// @notice The given currency address is unknown, invalid, or denied. error InvalidCurrency(); /// @notice The provided payment amount is incorrect. error InvalidPaymentAmount(); /// @notice The provided Merkle proof is invalid. error InvalidProof(); /// @notice This caller address has minted the maximum number of tokens allowed per address. error AddressMintedMaximum(); /// @notice The raise is not in Cancelled state. error RaiseNotCancelled(); /// @notice The raise is not in Funded state. error RaiseNotFunded(); /// @notice The raise has ended. error RaiseEnded(); /// @notice The raise is no longer in Active state. error RaiseInactive(); /// @notice The raise has not yet ended. error RaiseNotEnded(); /// @notice The raise has started and can no longer be updated. error RaiseHasStarted(); /// @notice The raise has not yet started and is in the Scheduled phase. error RaiseNotStarted(); /// @notice This token tier is sold out, or an attempt to mint would exceed the maximum supply. error RaiseSoldOut(); /// @notice The caller's token balance is zero. error ZeroBalance(); /// @notice One or both fees in the provided fee schedule equal or exceed 100%. error InvalidFeeSchedule(); event CreateRaise( uint32 indexed projectId, uint32 raiseId, RaiseParams params, TierParams[] tiers, address fanToken, address brandToken ); event UpdateRaise(uint32 indexed projectId, uint32 indexed raiseId, RaiseParams params, TierParams[] tiers); event Mint( uint32 indexed projectId, uint32 indexed raiseID, uint32 indexed tierId, address minter, uint256 amount, bytes32[] proof ); event SettleRaise(uint32 indexed projectId, uint32 indexed raiseId, RaiseState newState); event CancelRaise(uint32 indexed projectId, uint32 indexed raiseId, RaiseState newState); event CloseRaise(uint32 indexed projectId, uint32 indexed raiseId, RaiseState newState); event WithdrawRaiseFunds( uint32 indexed projectId, uint32 indexed raiseId, address indexed receiver, address currency, uint256 amount ); event Redeem( uint32 indexed projectId, uint32 indexed raiseID, uint32 indexed tierId, address receiver, uint256 tokenAmount, address owner, uint256 refundAmount ); event WithdrawFees(address indexed receiver, address currency, uint256 amount); event SetFeeSchedule(FeeSchedule oldFeeSchedule, FeeSchedule newFeeSchedule); event SetCreators(address oldCreators, address newCreators); event SetProjects(address oldProjects, address newProjects); event SetMinter(address oldMinter, address newMinter); event SetDeployer(address oldDeployer, address newDeployer); event SetTokens(address oldTokens, address newTokens); event SetTokenAuth(address oldTokenAuth, address newTokenAuth); /// @notice Create a new raise by project ID. May only be called by /// approved creators. /// @param projectId uint32 project ID. /// @param params RaiseParams raise configuration parameters struct. /// @param _tiers TierParams[] array of tier configuration parameters structs. /// @return raiseId Created raise ID. function create(uint32 projectId, RaiseParams memory params, TierParams[] memory _tiers) external returns (uint32 raiseId); /// @notice Update a Scheduled raise by project ID and raise ID. May only be /// called while the raise's state is Active and phase is Scheduled. /// @param projectId uint32 project ID. /// @param raiseId uint32 raise ID. /// @param params RaiseParams raise configuration parameters struct. /// @param _tiers TierParams[] array of tier configuration parameters structs. function update(uint32 projectId, uint32 raiseId, RaiseParams memory params, TierParams[] memory _tiers) external; /// @notice Mint `amount` of tokens to caller for the given `projectId`, /// `raiseId`, and `tierId`. Caller must provide ETH or approve ERC20 amount /// equal to total cost. /// @param projectId uint32 project ID. /// @param raiseId uint32 raise ID. /// @param tierId uint32 tier ID. /// @param amount uint256 quantity of tokens to mint. /// @return tokenId uint256 Minted token ID. function mint(uint32 projectId, uint32 raiseId, uint32 tierId, uint256 amount) external payable returns (uint256 tokenId); /// @notice Mint `amount` of tokens to caller for the given `projectId`, /// `raiseId`, and `tierId`. Caller must provide a Merkle proof. Caller must /// provide ETH or approve ERC20 amount equal to total cost. /// @param projectId uint32 project ID. /// @param raiseId uint32 raise ID. /// @param tierId uint32 tier ID. /// @param amount uint256 quantity of tokens to mint. /// @param proof bytes32[] Merkle proof of inclusion on tier allowlist. /// @return tokenId uint256 Minted token ID. function mint(uint32 projectId, uint32 raiseId, uint32 tierId, uint256 amount, bytes32[] memory proof) external payable returns (uint256 tokenId); /// @notice Settle a raise in the Active state and Ended phase. Sets raise /// state to Funded if the goal has been met. Sets raise state to Cancelled /// if the goal has not been met. /// @param projectId uint32 project ID. /// @param raiseId uint32 raise ID. function settle(uint32 projectId, uint32 raiseId) external; /// @notice Cancel a raise, setting its state to Cancelled. May only be /// called by `creators` contract. May only be called while raise state is Active. /// @param projectId uint32 project ID. /// @param raiseId uint32 raise ID. function cancel(uint32 projectId, uint32 raiseId) external; /// @notice Close a raise. May only be called by `creators` contract. May /// only be called if raise state is Active and raise goal is met. Sets /// state to Funded. /// @param projectId uint32 project ID. /// @param raiseId uint32 raise ID. function close(uint32 projectId, uint32 raiseId) external; /// @notice Withdraw raise funds to given `receiver` address. May only be /// called by `creators` contract. May only be called if raise state is Funded. /// @param projectId uint32 project ID. /// @param raiseId uint32 raise ID. /// @param receiver address send funds to this address. function withdraw(uint32 projectId, uint32 raiseId, address receiver) external; /// @notice Redeem `amount` of tokens from caller for the given `projectId`, /// `raiseId`, and `tierId` and return ETH or ERC20 tokens to caller. May /// only be called when raise state is Cancelled. /// @param projectId uint32 project ID. /// @param raiseId uint32 raise ID. /// @param tierId uint32 tier ID. /// @param amount uint256 quantity of tokens to redeem. function redeem(uint32 projectId, uint32 raiseId, uint32 tierId, uint256 amount) external; /// @notice Set a new fee schedule. May only be called by `controller` contract. /// @param _feeSchedule FeeSchedule new fee schedule. function setFeeSchedule(FeeSchedule calldata _feeSchedule) external; /// @notice Withdraw accrued protocol fees for given `currency` to given /// `receiver` address. May only be called by `controller` contract. /// @param currency address ERC20 token address or special sentinel value for ETH. /// @param receiver address send funds to this address. function withdrawFees(address currency, address receiver) external; /// @notice Get a raise by project ID and raise ID. /// @param projectId uint32 project ID. /// @param raiseId uint32 raise ID. /// @return Raise struct. function getRaise(uint32 projectId, uint32 raiseId) external view returns (Raise memory); /// @notice Get a raise's current Phase by project ID and raise ID. /// @param projectId uint32 project ID. /// @param raiseId uint32 raise ID. /// @return Phase enum member. function getPhase(uint32 projectId, uint32 raiseId) external view returns (Phase); /// @notice Get all tiers for a given raise by project ID and raise ID. /// @param projectId uint32 project ID. /// @param raiseId uint32 raise ID. /// @return Array of Tier structs. function getTiers(uint32 projectId, uint32 raiseId) external view returns (Tier[] memory); }
// SPDX-License-Identifier: MIT pragma solidity 0.8.17; import {IAllowList} from "./IAllowList.sol"; import {IAnnotated} from "./IAnnotated.sol"; interface ITokenAuth is IAllowList, IAnnotated {}
// SPDX-License-Identifier: MIT pragma solidity 0.8.17; import {IAllowList} from "./IAllowList.sol"; import {IAnnotated} from "./IAnnotated.sol"; interface ITokenDeployer is IAllowList, IAnnotated { event SetTokens(address oldTokens, address newTokens); function deploy() external returns (address); function register(uint256 id, address token) external; }
// SPDX-License-Identifier: MIT pragma solidity 0.8.17; import {IAnnotated} from "./IAnnotated.sol"; import {IControllable} from "./IControllable.sol"; import {IPausable} from "./IPausable.sol"; import {IEmint1155} from "./IEmint1155.sol"; interface ITokens is IControllable, IAnnotated { event SetMinter(address oldMinter, address newMinter); event SetDeployer(address oldDeployer, address newDeployer); event SetMetadata(address oldMetadata, address newMetadata); event SetRoyalties(address oldRoyalties, address newRoyalties); event UpdateTokenImplementation(address oldImpl, address newImpl); /// @notice Get address of metadata module. /// @return address of metadata module. function metadata() external view returns (address); /// @notice Get address of royalties module. /// @return address of royalties module. function royalties() external view returns (address); /// @notice Get deployed token for given token ID. /// @param tokenId uint256 token ID. /// @return IEmint1155 interface to deployed Emint1155 token contract. function token(uint256 tokenId) external view returns (IEmint1155); /// @notice Deploy an Emint1155 token. May only be called by token deployer. /// @return address of deployed Emint1155 token contract. function deploy() external returns (address); /// @notice Register a deployed token's address by token ID. /// May only be called by token deployer. /// @param tokenId uint256 token ID /// @param token address of deployed Emint1155 token contract. function register(uint256 tokenId, address token) external; /// @notice Update Emint1155 token implementation contract. Bytecode of this /// implementation contract will be cloned when deploying a new Emint1155. /// May only be called by controller. /// @param implementation address of implementation contract. function updateTokenImplementation(address implementation) external; /// @notice Mint `amount` tokens with ID `id` to `to` address, passing `data`. /// @param to address of token reciever. /// @param id uint256 token ID. /// @param amount uint256 quantity of tokens to mint. /// @param data bytes of data to pass to ERC1155 mint function. function mint(address to, uint256 id, uint256 amount, bytes memory data) external; }
// SPDX-License-Identifier: MIT pragma solidity 0.8.17; import {FeeSchedule} from "../structs/Raise.sol"; import {TierType} from "../structs/Tier.sol"; uint256 constant BPS_DENOMINATOR = 10_000; error ValidationError(string message); /// @title Fees - Fee calculator /// @notice Calculates protocol fee based on token mint price. library Fees { function validate(FeeSchedule memory fees) internal pure { if (fees.fanFee >= BPS_DENOMINATOR) { revert ValidationError("invalid fanFee"); } if (fees.brandFee >= BPS_DENOMINATOR) { revert ValidationError("invalid brandFee"); } } function calculate(FeeSchedule storage fees, TierType tierType, uint256 mintPrice) internal view returns (uint256 protocolFee, uint256 creatorTake) { uint256 feeBps = (tierType == TierType.Fan) ? fees.fanFee : fees.brandFee; protocolFee = (feeBps * mintPrice) / BPS_DENOMINATOR; creatorTake = mintPrice - protocolFee; } }
// SPDX-License-Identifier: MIT pragma solidity 0.8.17; import {Raise, Phase} from "../structs/Raise.sol"; /// @title Phases - Raise schedule calculator /// @notice Calculates a raise's "phase" based on the current timestamp and the /// raise's configured schedule. library Phases { function phase(Raise memory raise) internal view returns (Phase) { // If it's before presale start, the raise is scheduled if (block.timestamp < raise.timestamps.presaleStart) { return Phase.Scheduled; } // If it's after public sale end, the raise has ended if (block.timestamp > raise.timestamps.publicSaleEnd) { return Phase.Ended; } // We are somewhere between presale start and public sale end. if (block.timestamp >= raise.timestamps.publicSaleStart) { // If it's after public sale start, we are in public sale. return Phase.PublicSale; } else { // Presale and public sale might not be continuous, so we may return // to the scheduled phase... if (block.timestamp > raise.timestamps.presaleEnd) { // If it's after presale end, we are back in scheduled. return Phase.Scheduled; } else { // Otherwise, we must be in presale. return Phase.Presale; } } } }
// SPDX-License-Identifier: MIT pragma solidity 0.8.17; import {TokenCodec} from "./codecs/TokenCodec.sol"; import {RaiseCodec} from "./codecs/RaiseCodec.sol"; import {TokenData, TokenType} from "../structs/TokenData.sol"; import {RaiseData, TierType} from "../structs/RaiseData.sol"; import {TWO_BYTES} from "../constants/Codecs.sol"; // |------------ Token data is encoded in 32 bytes ---------------| // 0x0000000000000000000000000000000000000000000000000000000000000000 // 1 byte token type tt // 1 byte encoding version vv // |------- Raise token data is encoded in 30 bytes ----------| // 4 byte project ID pppppppp // 4 byte raise ID rrrrrrrr // 4 byte tier ID tttttttt // 1 byte tier type TT // |------- 17 empty bytes --------| /// @title RaiseToken - Raise token encoder/decoder /// @notice Converts numeric token IDs to TokenData/RaiseData structs. library RaiseToken { function encode(TierType _tierType, uint32 _projectId, uint32 _raiseId, uint32 _tierId) internal pure returns (uint256) { RaiseData memory raiseData = RaiseData({tierType: _tierType, projectId: _projectId, raiseId: _raiseId, tierId: _tierId}); TokenData memory tokenData = TokenData({tokenType: TokenType.Raise, encodingVersion: 0, data: RaiseCodec.encode(raiseData)}); return TokenCodec.encode(tokenData); } function decode(uint256 tokenId) internal pure returns (TokenData memory, RaiseData memory) { TokenData memory token = TokenCodec.decode(tokenId); RaiseData memory raise = RaiseCodec.decode(token.data); return (token, raise); } function projectId(uint256 tokenId) internal pure returns (uint32) { return uint32(tokenId >> TWO_BYTES); } }
// SPDX-License-Identifier: MIT pragma solidity 0.8.17; import {RaiseData, TierType} from "../../structs/RaiseData.sol"; import {ONE_BYTE, ONE_BYTE_MASK, FOUR_BYTES, FOUR_BYTE_MASK} from "../../constants/Codecs.sol"; // |-------- Raise token data is encoded in 30 bytes -----------| // 0x000000000000000000000000000000000000000000000000000000000000 // 4 byte project ID pppppppp // 4 byte raise ID rrrrrrrr // 4 byte tier ID tttttttt // 1 byte tier type TT // ---------------------------------- 17 empty bytes reserved uint240 constant PROJECT_ID_SIZE = uint240(FOUR_BYTES); uint240 constant RAISE_ID_SIZE = uint240(FOUR_BYTES); uint240 constant TIER_ID_SIZE = uint240(FOUR_BYTES); uint240 constant TIER_TYPE_SIZE = uint240(ONE_BYTE); uint240 constant RAISE_ID_OFFSET = PROJECT_ID_SIZE; uint240 constant TIER_ID_OFFSET = RAISE_ID_OFFSET + RAISE_ID_SIZE; uint240 constant TIER_TYPE_OFFSET = TIER_ID_OFFSET + TIER_ID_SIZE; uint240 constant PROJECT_ID_MASK = uint240(FOUR_BYTE_MASK); uint240 constant RAISE_ID_MASK = uint240(FOUR_BYTE_MASK) << RAISE_ID_OFFSET; uint240 constant TIER_ID_MASK = uint240(FOUR_BYTE_MASK) << TIER_ID_OFFSET; uint240 constant TIER_TYPE_MASK = uint240(ONE_BYTE_MASK) << TIER_TYPE_OFFSET; bytes17 constant RESERVED_REGION = 0x0; /// @title RaiseCodec - Raise token encoder/decoder /// @notice Converts between token data bytes and RaiseData struct. library RaiseCodec { function encode(RaiseData memory raise) internal pure returns (bytes30) { bytes memory encoded = abi.encodePacked(RESERVED_REGION, raise.tierType, raise.tierId, raise.raiseId, raise.projectId); return bytes30(encoded); } function decode(bytes30 tokenData) internal pure returns (RaiseData memory) { uint240 bits = uint240(tokenData); uint32 projectId = uint32(bits & PROJECT_ID_MASK); uint32 raiseId = uint32((bits & RAISE_ID_MASK) >> RAISE_ID_OFFSET); uint32 tierId = uint32((bits & TIER_ID_MASK) >> TIER_ID_OFFSET); TierType tierType = TierType((bits & TIER_TYPE_MASK) >> TIER_TYPE_OFFSET); return RaiseData({tierType: tierType, tierId: tierId, raiseId: raiseId, projectId: projectId}); } }
// SPDX-License-Identifier: MIT pragma solidity 0.8.17; import {TokenData, TokenType} from "../../structs/TokenData.sol"; import {ONE_BYTE, ONE_BYTE_MASK, THIRTY_BYTE_MASK} from "../../constants/Codecs.sol"; // |------------ Token data is encoded in 32 bytes ---------------| // 0x0000000000000000000000000000000000000000000000000000000000000000 // 1 byte token type tt // 1 byte encoding version vv // |------------------ 30 byte data region -------------------| uint256 constant TOKEN_TYPE_SIZE = ONE_BYTE; uint256 constant ENCODING_SIZE = ONE_BYTE; uint256 constant ENCODING_OFFSET = TOKEN_TYPE_SIZE; uint256 constant DATA_OFFSET = ENCODING_OFFSET + ENCODING_SIZE; uint256 constant TOKEN_TYPE_MASK = ONE_BYTE_MASK; uint256 constant ENCODING_VERSION_MASK = ONE_BYTE_MASK << ENCODING_OFFSET; uint256 constant DATA_REGION_MASK = THIRTY_BYTE_MASK << DATA_OFFSET; /// @title RaiseCodec - Token encoder/decoder /// @notice Converts between token ID and TokenData struct. library TokenCodec { function encode(TokenData memory token) internal pure returns (uint256) { bytes memory encoded = abi.encodePacked(token.data, token.encodingVersion, token.tokenType); return uint256(bytes32(encoded)); } function decode(uint256 tokenId) internal pure returns (TokenData memory) { TokenType tokenType = TokenType(tokenId & TOKEN_TYPE_MASK); uint8 encodingVersion = uint8((tokenId & ENCODING_VERSION_MASK) >> ENCODING_OFFSET); bytes30 data = bytes30(uint240((tokenId & DATA_REGION_MASK) >> DATA_OFFSET)); return TokenData({tokenType: tokenType, encodingVersion: encodingVersion, data: data}); } }
// SPDX-License-Identifier: MIT pragma solidity 0.8.17; import {RaiseParams, RaiseState} from "../../structs/Raise.sol"; import {ITokenAuth} from "../../interfaces/ITokenAuth.sol"; import {ETH} from "../../constants/Constants.sol"; error ValidationError(string message); library RaiseValidator { function validate(RaiseParams memory params, address allowlist) internal view { // Currency must be allowlisted if (params.currency != ETH) { if (ITokenAuth(allowlist).denied(params.currency)) revert ValidationError("invalid token"); } // Zero max means "no maximum" if (params.max > 0) { // The raise goal cannot be greater than the raise max if (params.max < params.goal) { revert ValidationError("max < goal"); } } // End times must be after start times if (params.presaleEnd < params.presaleStart) { revert ValidationError("end < start"); } if (params.publicSaleEnd <= params.publicSaleStart) { revert ValidationError("end <= start"); } // Public start must be equal to or after presale end if (params.publicSaleStart < params.presaleEnd) { revert ValidationError("public < presale"); } // Start time must be now or in future. Since we know public start // is after presale end and all end times are after start times, // we only have to check presale start here. if (params.presaleStart < block.timestamp) { revert ValidationError("start <= now"); } // Max length of phases is 1 year if (params.presaleEnd - params.presaleStart > 365 days) { revert ValidationError("too long"); } if (params.publicSaleEnd - params.publicSaleStart > 365 days) { revert ValidationError("too long"); } } }
// SPDX-License-Identifier: MIT pragma solidity 0.8.17; import {TierParams} from "../../structs/Tier.sol"; error ValidationError(string message); /// @title TierValidator - Tier parameter validator library TierValidator { function validate(TierParams memory tier) internal pure { if (tier.supply == 0) { revert ValidationError("zero supply"); } if (tier.limitPerAddress == 0) { revert ValidationError("zero limit"); } } }
// SPDX-License-Identifier: MIT pragma solidity 0.8.17; import {Tier} from "./Tier.sol"; /// @param goal Target amount to raise. If a raise meets its goal amount, the /// raise settles as Funded, users keep their tokens, and the owner may withdraw /// the collected funds. If a raise fails to meet its goual the raise settles as /// Cancelled and users may redeem their tokens for a refund. /// @param max Maximum amount to raise. /// @param presaleStart Start timestamp of the presale phase. During this phase, /// allowlisted users may mint tokens by providing a Merkle proof. /// @param presaleEnd End timestamp of the presale phase. /// @param publicSaleStart Start timestamp of the public sale phase. During this /// phase, any user may mint a token. /// @param publicSaleEnd End timestamp of the public sale phase. /// @param currency Currency for this raise, either an ERC20 token address, or /// the "dolphin address" for ETH. ERC20 tokens must be allowed by TokenAuth. struct RaiseParams { uint256 goal; uint256 max; uint64 presaleStart; uint64 presaleEnd; uint64 publicSaleStart; uint64 publicSaleEnd; address currency; } /// @notice A raise may be in one of three states, depending on whether it has /// ended and has or has not met its goal: /// - An Active raise has not yet ended. /// - A Funded raise has ended and met its goal. /// - A Cancelled raise has ended and either did not meet its goal or was /// cancelled by the raise creator. enum RaiseState { Active, Funded, Cancelled } /// @param goal Target amount to raise. If a raise meets its goal amount, the /// raise settles as Funded, users keep their tokens, and the owner may withdraw /// the collected funds. If a raise fails to meet its goual the raise settles as /// Cancelled and users may redeem their tokens for a refund. /// @param max Maximum amount to raise. /// @param timestamps Struct containing presale and public sale start/end times. /// @param currency Currency for this raise, either an ERC20 token address, or /// the "dolphin address" for ETH. ERC20 tokens must be allowed by TokenAuth. /// @param state State of the raise. All new raises begin in Active state. /// @param projectId Integer ID of the project associated with this raise. /// @param raiseId Integer ID of this raise. /// @param tokens Struct containing addresses of this raise's tokens. /// @param feeSchedule Struct containing fee schedule for this raise. /// @param raised Total amount of ETH or ERC20 token contributed to this raise. /// @param balance Creator's share of the total amount raised. /// @param fees Protocol fees from this raise. raised = balance + fees struct Raise { uint256 goal; uint256 max; RaiseTimestamps timestamps; address currency; RaiseState state; uint32 projectId; uint32 raiseId; RaiseTokens tokens; FeeSchedule feeSchedule; uint256 raised; uint256 balance; uint256 fees; } /// @param presaleStart Start timestamp of the presale phase. During this phase, /// allowlisted users may mint tokens by providing a Merkle proof. /// @param presaleEnd End timestamp of the presale phase. /// @param publicSaleStart Start timestamp of the public sale phase. During this /// phase, any user may mint a token. /// @param publicSaleEnd End timestamp of the public sale phase. struct RaiseTimestamps { uint64 presaleStart; uint64 presaleEnd; uint64 publicSaleStart; uint64 publicSaleEnd; } /// @param fanToken Address of this raise's ERC1155 fan token. /// @param brandToken Address of this raise's ERC1155 brand token. struct RaiseTokens { address fanToken; address brandToken; } /// @param fanFee Protocol fee in basis points for fan token sales. /// @param brandFee Protocol fee in basis poitns for brand token sales. struct FeeSchedule { uint16 fanFee; uint16 brandFee; } /// @notice A raise may be in one of four phases, depending on the timestamps of /// its presale and public sale phases: /// - A Scheduled raise is not open for minting. If a raise is Scheduled, it is /// currently either before the Presale phase or between Presale and PublicSale. /// - The Presale phase is between the presale start and presale end timestamps. /// - The PublicSale phase is between the public sale start and public sale end /// timestamps. PublicSale must be after Presale, but the raise may return to /// the Scheduled phase in between. /// - After the public sale end timestamp, the raise has Ended. enum Phase { Scheduled, Presale, PublicSale, Ended }
// SPDX-License-Identifier: MIT pragma solidity 0.8.17; import {TierType} from "./Tier.sol"; /// @param projectId Integer ID of the project associated with this raise token. /// @param raiseId Integer ID of the raise associated with this raise token. /// @param tierId Integer ID of the tier associated with this raise token. /// @param tierType Enum indicating whether this is a "fan" or "brand" token. struct RaiseData { uint32 projectId; uint32 raiseId; uint32 tierId; TierType tierType; }
// SPDX-License-Identifier: MIT pragma solidity 0.8.17; /// @notice Enum indicating whether a token is a "fan" or "brand" token. Fan /// tokens are intended for purchase by project patrons and have a lower protocol /// fee and royalties than brand tokens. enum TierType { Fan, Brand } /// @param tierType Whether this tier is a "fan" or "brand" token. /// @param supply Maximum token supply in this tier. /// @param price Price per token. /// @param limitPerAddress Maximum number of tokens that may be minted by address. /// @param allowListRoot Merkle root of an allowlist for the presale phase. struct TierParams { TierType tierType; uint256 supply; uint256 price; uint256 limitPerAddress; bytes32 allowListRoot; } /// @param tierType Whether this tier is a "fan" or "brand" token. /// @param supply Maximum token supply in this tier. /// @param price Price per token. /// @param limitPerAddress Maximum number of tokens that may be minted by address. /// @param allowListRoot Merkle root of an allowlist for the presale phase. /// @param minted Total number of tokens minted in this tier. struct Tier { TierType tierType; uint256 supply; uint256 price; uint256 limitPerAddress; bytes32 allowListRoot; uint256 minted; }
// SPDX-License-Identifier: MIT pragma solidity 0.8.17; /// @notice Enum representing token types. The V1 protocol supports only one /// token type, "Raise," which represents a crowdfund contribution. However, /// new token types may be added in the future. enum TokenType {Raise} /// @param data 30-byte data region containing encoded token data. The specific /// format of this data depends on encoding version and token type. /// @param encodingVersion Encoding version of this token. /// @param tokenType Enum indicating type of this token. (e.g. Raise) struct TokenData { bytes30 data; uint8 encodingVersion; TokenType tokenType; }
{ "remappings": [ "ds-test/=lib/ds-test/src/", "erc4626-tests/=lib/operator-filter-registry/lib/openzeppelin-contracts/lib/erc4626-tests/", "forge-std/=lib/forge-std/src/", "openzeppelin-contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/", "openzeppelin-contracts/=lib/openzeppelin-contracts/contracts/", "operator-filter-registry/=lib/operator-filter-registry/src/" ], "optimizer": { "enabled": true, "runs": 200 }, "metadata": { "bytecodeHash": "ipfs" }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "evmVersion": "london", "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"address","name":"_controller","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"AddressMintedMaximum","type":"error"},{"inputs":[],"name":"ExceedsRaiseMaximum","type":"error"},{"inputs":[],"name":"Forbidden","type":"error"},{"inputs":[],"name":"InvalidCurrency","type":"error"},{"inputs":[{"internalType":"bytes32","name":"name","type":"bytes32"}],"name":"InvalidDependency","type":"error"},{"inputs":[],"name":"InvalidFeeSchedule","type":"error"},{"inputs":[],"name":"InvalidPaymentAmount","type":"error"},{"inputs":[],"name":"InvalidProof","type":"error"},{"inputs":[],"name":"NotFound","type":"error"},{"inputs":[],"name":"RaiseEnded","type":"error"},{"inputs":[],"name":"RaiseGoalNotMet","type":"error"},{"inputs":[],"name":"RaiseHasStarted","type":"error"},{"inputs":[],"name":"RaiseInactive","type":"error"},{"inputs":[],"name":"RaiseNotCancelled","type":"error"},{"inputs":[],"name":"RaiseNotEnded","type":"error"},{"inputs":[],"name":"RaiseNotFunded","type":"error"},{"inputs":[],"name":"RaiseNotStarted","type":"error"},{"inputs":[],"name":"RaiseSoldOut","type":"error"},{"inputs":[{"internalType":"string","name":"message","type":"string"}],"name":"ValidationError","type":"error"},{"inputs":[{"internalType":"string","name":"message","type":"string"}],"name":"ValidationError","type":"error"},{"inputs":[{"internalType":"string","name":"message","type":"string"}],"name":"ValidationError","type":"error"},{"inputs":[],"name":"ZeroAddress","type":"error"},{"inputs":[],"name":"ZeroBalance","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint32","name":"projectId","type":"uint32"},{"indexed":true,"internalType":"uint32","name":"raiseId","type":"uint32"},{"indexed":false,"internalType":"enum RaiseState","name":"newState","type":"uint8"}],"name":"CancelRaise","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint32","name":"projectId","type":"uint32"},{"indexed":true,"internalType":"uint32","name":"raiseId","type":"uint32"},{"indexed":false,"internalType":"enum RaiseState","name":"newState","type":"uint8"}],"name":"CloseRaise","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint32","name":"projectId","type":"uint32"},{"indexed":false,"internalType":"uint32","name":"raiseId","type":"uint32"},{"components":[{"internalType":"uint256","name":"goal","type":"uint256"},{"internalType":"uint256","name":"max","type":"uint256"},{"internalType":"uint64","name":"presaleStart","type":"uint64"},{"internalType":"uint64","name":"presaleEnd","type":"uint64"},{"internalType":"uint64","name":"publicSaleStart","type":"uint64"},{"internalType":"uint64","name":"publicSaleEnd","type":"uint64"},{"internalType":"address","name":"currency","type":"address"}],"indexed":false,"internalType":"struct RaiseParams","name":"params","type":"tuple"},{"components":[{"internalType":"enum TierType","name":"tierType","type":"uint8"},{"internalType":"uint256","name":"supply","type":"uint256"},{"internalType":"uint256","name":"price","type":"uint256"},{"internalType":"uint256","name":"limitPerAddress","type":"uint256"},{"internalType":"bytes32","name":"allowListRoot","type":"bytes32"}],"indexed":false,"internalType":"struct TierParams[]","name":"tiers","type":"tuple[]"},{"indexed":false,"internalType":"address","name":"fanToken","type":"address"},{"indexed":false,"internalType":"address","name":"brandToken","type":"address"}],"name":"CreateRaise","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint32","name":"projectId","type":"uint32"},{"indexed":true,"internalType":"uint32","name":"raiseID","type":"uint32"},{"indexed":true,"internalType":"uint32","name":"tierId","type":"uint32"},{"indexed":false,"internalType":"address","name":"minter","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"bytes32[]","name":"proof","type":"bytes32[]"}],"name":"Mint","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint32","name":"projectId","type":"uint32"},{"indexed":true,"internalType":"uint32","name":"raiseID","type":"uint32"},{"indexed":true,"internalType":"uint32","name":"tierId","type":"uint32"},{"indexed":false,"internalType":"address","name":"receiver","type":"address"},{"indexed":false,"internalType":"uint256","name":"tokenAmount","type":"uint256"},{"indexed":false,"internalType":"address","name":"owner","type":"address"},{"indexed":false,"internalType":"uint256","name":"refundAmount","type":"uint256"}],"name":"Redeem","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"oldCreators","type":"address"},{"indexed":false,"internalType":"address","name":"newCreators","type":"address"}],"name":"SetCreators","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"oldDeployer","type":"address"},{"indexed":false,"internalType":"address","name":"newDeployer","type":"address"}],"name":"SetDeployer","type":"event"},{"anonymous":false,"inputs":[{"components":[{"internalType":"uint16","name":"fanFee","type":"uint16"},{"internalType":"uint16","name":"brandFee","type":"uint16"}],"indexed":false,"internalType":"struct FeeSchedule","name":"oldFeeSchedule","type":"tuple"},{"components":[{"internalType":"uint16","name":"fanFee","type":"uint16"},{"internalType":"uint16","name":"brandFee","type":"uint16"}],"indexed":false,"internalType":"struct FeeSchedule","name":"newFeeSchedule","type":"tuple"}],"name":"SetFeeSchedule","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"oldMinter","type":"address"},{"indexed":false,"internalType":"address","name":"newMinter","type":"address"}],"name":"SetMinter","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"oldProjects","type":"address"},{"indexed":false,"internalType":"address","name":"newProjects","type":"address"}],"name":"SetProjects","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"oldTokenAuth","type":"address"},{"indexed":false,"internalType":"address","name":"newTokenAuth","type":"address"}],"name":"SetTokenAuth","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"oldTokens","type":"address"},{"indexed":false,"internalType":"address","name":"newTokens","type":"address"}],"name":"SetTokens","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint32","name":"projectId","type":"uint32"},{"indexed":true,"internalType":"uint32","name":"raiseId","type":"uint32"},{"indexed":false,"internalType":"enum RaiseState","name":"newState","type":"uint8"}],"name":"SettleRaise","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint32","name":"projectId","type":"uint32"},{"indexed":true,"internalType":"uint32","name":"raiseId","type":"uint32"},{"components":[{"internalType":"uint256","name":"goal","type":"uint256"},{"internalType":"uint256","name":"max","type":"uint256"},{"internalType":"uint64","name":"presaleStart","type":"uint64"},{"internalType":"uint64","name":"presaleEnd","type":"uint64"},{"internalType":"uint64","name":"publicSaleStart","type":"uint64"},{"internalType":"uint64","name":"publicSaleEnd","type":"uint64"},{"internalType":"address","name":"currency","type":"address"}],"indexed":false,"internalType":"struct RaiseParams","name":"params","type":"tuple"},{"components":[{"internalType":"enum TierType","name":"tierType","type":"uint8"},{"internalType":"uint256","name":"supply","type":"uint256"},{"internalType":"uint256","name":"price","type":"uint256"},{"internalType":"uint256","name":"limitPerAddress","type":"uint256"},{"internalType":"bytes32","name":"allowListRoot","type":"bytes32"}],"indexed":false,"internalType":"struct TierParams[]","name":"tiers","type":"tuple[]"}],"name":"UpdateRaise","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"receiver","type":"address"},{"indexed":false,"internalType":"address","name":"currency","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"WithdrawFees","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint32","name":"projectId","type":"uint32"},{"indexed":true,"internalType":"uint32","name":"raiseId","type":"uint32"},{"indexed":true,"internalType":"address","name":"receiver","type":"address"},{"indexed":false,"internalType":"address","name":"currency","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"WithdrawRaiseFunds","type":"event"},{"inputs":[],"name":"NAME","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"VERSION","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"projectId","type":"uint32"},{"internalType":"uint32","name":"raiseId","type":"uint32"}],"name":"cancel","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint32","name":"projectId","type":"uint32"},{"internalType":"uint32","name":"raiseId","type":"uint32"}],"name":"close","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"controller","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"projectId","type":"uint32"},{"components":[{"internalType":"uint256","name":"goal","type":"uint256"},{"internalType":"uint256","name":"max","type":"uint256"},{"internalType":"uint64","name":"presaleStart","type":"uint64"},{"internalType":"uint64","name":"presaleEnd","type":"uint64"},{"internalType":"uint64","name":"publicSaleStart","type":"uint64"},{"internalType":"uint64","name":"publicSaleEnd","type":"uint64"},{"internalType":"address","name":"currency","type":"address"}],"internalType":"struct RaiseParams","name":"params","type":"tuple"},{"components":[{"internalType":"enum TierType","name":"tierType","type":"uint8"},{"internalType":"uint256","name":"supply","type":"uint256"},{"internalType":"uint256","name":"price","type":"uint256"},{"internalType":"uint256","name":"limitPerAddress","type":"uint256"},{"internalType":"bytes32","name":"allowListRoot","type":"bytes32"}],"internalType":"struct TierParams[]","name":"_tiers","type":"tuple[]"}],"name":"create","outputs":[{"internalType":"uint32","name":"raiseId","type":"uint32"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"creators","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"deployer","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"feeSchedule","outputs":[{"internalType":"uint16","name":"fanFee","type":"uint16"},{"internalType":"uint16","name":"brandFee","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"fees","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"projectId","type":"uint32"},{"internalType":"uint32","name":"raiseId","type":"uint32"}],"name":"getPhase","outputs":[{"internalType":"enum Phase","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"projectId","type":"uint32"},{"internalType":"uint32","name":"raiseId","type":"uint32"}],"name":"getRaise","outputs":[{"components":[{"internalType":"uint256","name":"goal","type":"uint256"},{"internalType":"uint256","name":"max","type":"uint256"},{"components":[{"internalType":"uint64","name":"presaleStart","type":"uint64"},{"internalType":"uint64","name":"presaleEnd","type":"uint64"},{"internalType":"uint64","name":"publicSaleStart","type":"uint64"},{"internalType":"uint64","name":"publicSaleEnd","type":"uint64"}],"internalType":"struct RaiseTimestamps","name":"timestamps","type":"tuple"},{"internalType":"address","name":"currency","type":"address"},{"internalType":"enum RaiseState","name":"state","type":"uint8"},{"internalType":"uint32","name":"projectId","type":"uint32"},{"internalType":"uint32","name":"raiseId","type":"uint32"},{"components":[{"internalType":"address","name":"fanToken","type":"address"},{"internalType":"address","name":"brandToken","type":"address"}],"internalType":"struct RaiseTokens","name":"tokens","type":"tuple"},{"components":[{"internalType":"uint16","name":"fanFee","type":"uint16"},{"internalType":"uint16","name":"brandFee","type":"uint16"}],"internalType":"struct FeeSchedule","name":"feeSchedule","type":"tuple"},{"internalType":"uint256","name":"raised","type":"uint256"},{"internalType":"uint256","name":"balance","type":"uint256"},{"internalType":"uint256","name":"fees","type":"uint256"}],"internalType":"struct Raise","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"projectId","type":"uint32"},{"internalType":"uint32","name":"raiseId","type":"uint32"}],"name":"getTiers","outputs":[{"components":[{"internalType":"enum TierType","name":"tierType","type":"uint8"},{"internalType":"uint256","name":"supply","type":"uint256"},{"internalType":"uint256","name":"price","type":"uint256"},{"internalType":"uint256","name":"limitPerAddress","type":"uint256"},{"internalType":"bytes32","name":"allowListRoot","type":"bytes32"},{"internalType":"uint256","name":"minted","type":"uint256"}],"internalType":"struct Tier[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"projectId","type":"uint32"},{"internalType":"uint32","name":"raiseId","type":"uint32"},{"internalType":"uint32","name":"tierId","type":"uint32"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"mint","outputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint32","name":"projectId","type":"uint32"},{"internalType":"uint32","name":"raiseId","type":"uint32"},{"internalType":"uint32","name":"tierId","type":"uint32"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes32[]","name":"proof","type":"bytes32[]"}],"name":"mint","outputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"minter","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"","type":"uint32"},{"internalType":"uint32","name":"","type":"uint32"},{"internalType":"uint32","name":"","type":"uint32"},{"internalType":"address","name":"","type":"address"}],"name":"mints","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"projects","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"","type":"uint32"},{"internalType":"uint32","name":"","type":"uint32"}],"name":"raises","outputs":[{"internalType":"uint256","name":"goal","type":"uint256"},{"internalType":"uint256","name":"max","type":"uint256"},{"components":[{"internalType":"uint64","name":"presaleStart","type":"uint64"},{"internalType":"uint64","name":"presaleEnd","type":"uint64"},{"internalType":"uint64","name":"publicSaleStart","type":"uint64"},{"internalType":"uint64","name":"publicSaleEnd","type":"uint64"}],"internalType":"struct RaiseTimestamps","name":"timestamps","type":"tuple"},{"internalType":"address","name":"currency","type":"address"},{"internalType":"enum RaiseState","name":"state","type":"uint8"},{"internalType":"uint32","name":"projectId","type":"uint32"},{"internalType":"uint32","name":"raiseId","type":"uint32"},{"components":[{"internalType":"address","name":"fanToken","type":"address"},{"internalType":"address","name":"brandToken","type":"address"}],"internalType":"struct RaiseTokens","name":"tokens","type":"tuple"},{"components":[{"internalType":"uint16","name":"fanFee","type":"uint16"},{"internalType":"uint16","name":"brandFee","type":"uint16"}],"internalType":"struct FeeSchedule","name":"feeSchedule","type":"tuple"},{"internalType":"uint256","name":"raised","type":"uint256"},{"internalType":"uint256","name":"balance","type":"uint256"},{"internalType":"uint256","name":"fees","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"projectId","type":"uint32"},{"internalType":"uint32","name":"raiseId","type":"uint32"},{"internalType":"uint32","name":"tierId","type":"uint32"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"redeem","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_name","type":"bytes32"},{"internalType":"address","name":"_contract","type":"address"}],"name":"setDependency","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"uint16","name":"fanFee","type":"uint16"},{"internalType":"uint16","name":"brandFee","type":"uint16"}],"internalType":"struct FeeSchedule","name":"newFeeSchedule","type":"tuple"}],"name":"setFeeSchedule","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint32","name":"projectId","type":"uint32"},{"internalType":"uint32","name":"raiseId","type":"uint32"}],"name":"settle","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint32","name":"","type":"uint32"},{"internalType":"uint32","name":"","type":"uint32"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"tiers","outputs":[{"internalType":"enum TierType","name":"tierType","type":"uint8"},{"internalType":"uint256","name":"supply","type":"uint256"},{"internalType":"uint256","name":"price","type":"uint256"},{"internalType":"uint256","name":"limitPerAddress","type":"uint256"},{"internalType":"bytes32","name":"allowListRoot","type":"bytes32"},{"internalType":"uint256","name":"minted","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tokenAuth","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tokens","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"","type":"uint32"}],"name":"totalRaises","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"unpause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint32","name":"projectId","type":"uint32"},{"internalType":"uint32","name":"raiseId","type":"uint32"},{"components":[{"internalType":"uint256","name":"goal","type":"uint256"},{"internalType":"uint256","name":"max","type":"uint256"},{"internalType":"uint64","name":"presaleStart","type":"uint64"},{"internalType":"uint64","name":"presaleEnd","type":"uint64"},{"internalType":"uint64","name":"publicSaleStart","type":"uint64"},{"internalType":"uint64","name":"publicSaleEnd","type":"uint64"},{"internalType":"address","name":"currency","type":"address"}],"internalType":"struct RaiseParams","name":"params","type":"tuple"},{"components":[{"internalType":"enum TierType","name":"tierType","type":"uint8"},{"internalType":"uint256","name":"supply","type":"uint256"},{"internalType":"uint256","name":"price","type":"uint256"},{"internalType":"uint256","name":"limitPerAddress","type":"uint256"},{"internalType":"bytes32","name":"allowListRoot","type":"bytes32"}],"internalType":"struct TierParams[]","name":"_tiers","type":"tuple[]"}],"name":"update","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint32","name":"projectId","type":"uint32"},{"internalType":"uint32","name":"raiseId","type":"uint32"},{"internalType":"address","name":"receiver","type":"address"}],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"currency","type":"address"},{"internalType":"address","name":"receiver","type":"address"}],"name":"withdrawFees","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
60c06040526101f46080526109c460a0526008805463ffffffff19166309c401f41790553480156200003057600080fd5b5060405162004794380380620047948339810160408190526200005391620000a6565b806001600160a01b0381166200007c5760405163d92e233d60e01b815260040160405180910390fd5b600080546001600160a81b0319166001600160a01b039092169190911790555060018055620000d8565b600060208284031215620000b957600080fd5b81516001600160a01b0381168114620000d157600080fd5b9392505050565b6146ac80620000e86000396000f3fe6080604052600436106101ee5760003560e01c80638ee90dca1161010d578063c509b0be116100a0578063e0b0f21c1161006f578063e0b0f21c14610747578063f255527814610767578063f77c479114610787578063faaebd21146107a7578063ffa1ad74146107d457600080fd5b8063c509b0be146106a7578063c7a0152a146106c7578063d478cd57146106e7578063d5f394881461072757600080fd5b8063aae01773116100dc578063aae01773146105f2578063b13a05fd1461061f578063b9468e911461063f578063bd174da81461065f57600080fd5b80638ee90dca1461052c5780639d63848a1461054c578063a3f4df7e1461056c578063a885cf61146105ab57600080fd5b8063515d74d6116101855780637238695e116101545780637238695e146104b75780638456cb59146104d757806384cea36e146104ec5780638b79543c1461050c57600080fd5b8063515d74d6146103275780635964abde146103545780635b5155721461047a5780635c975abb1461048d57600080fd5b806332b91fb6116101c157806332b91fb61461029f5780633e35b137146102d15780633f4ba83a146102f257806344d851521461030757600080fd5b806307546172146101f357806311c5c7da14610230578063251af3521461025d5780632f2fc4161461027f575b600080fd5b3480156101ff57600080fd5b50600454610213906001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b34801561023c57600080fd5b5061025061024b36600461385d565b610805565b60405161022791906138ba565b34801561026957600080fd5b5061027d61027836600461385d565b610a11565b005b34801561028b57600080fd5b50600254610213906001600160a01b031681565b3480156102ab57600080fd5b506102bf6102ba3660046139db565b610d02565b60405161022796959493929190613a27565b6102e46102df366004613a5d565b610d67565b604051908152602001610227565b3480156102fe57600080fd5b5061027d610dc4565b34801561031357600080fd5b5061027d610322366004613abd565b610df9565b34801561033357600080fd5b5061034761034236600461385d565b610f42565b6040516102279190613b04565b34801561036057600080fd5b5061046261036f36600461385d565b600a60209081526000928352604080842082529183529181902080546001820154835160808101855260028401546001600160401b038082168352600160401b8204811683890152600160801b8204811683880152600160c01b90910416606082015260038401548551808701875260048601546001600160a01b03908116825260058701548116828a01528751808901909852600687015461ffff8082168a52620100009091041698880198909852600786015460088701546009909701549598949793969483169560ff600160a01b8504169563ffffffff600160a81b8604811696600160c81b909604169492918c565b6040516102279c9b9a99989796959493929190613b1e565b6102e4610488366004613c88565b610fff565b34801561049957600080fd5b50600054600160a01b900460ff166040519015158152602001610227565b3480156104c357600080fd5b5061027d6104d2366004613d5b565b611032565b3480156104e357600080fd5b5061027d611148565b3480156104f857600080fd5b50600754610213906001600160a01b031681565b34801561051857600080fd5b50600354610213906001600160a01b031681565b34801561053857600080fd5b5061027d610547366004613f01565b61117b565b34801561055857600080fd5b50600654610213906001600160a01b031681565b34801561057857600080fd5b5061059e6040518060400160405280600681526020016552616973657360d01b81525081565b6040516102279190613f96565b3480156105b757600080fd5b506102e46105c6366004613fc9565b600c60209081526000948552604080862082529385528385208152918452828420909152825290205481565b3480156105fe57600080fd5b5061061261060d36600461385d565b6112ed565b604051610227919061401f565b34801561062b57600080fd5b5061027d61063a36600461385d565b6113d3565b34801561064b57600080fd5b5061027d61065a36600461385d565b61149e565b34801561066b57600080fd5b5061069261067a36600461409e565b60096020526000908152604090205463ffffffff1681565b60405163ffffffff9091168152602001610227565b3480156106b357600080fd5b506106926106c23660046140b9565b6115db565b3480156106d357600080fd5b5061027d6106e2366004614119565b611885565b3480156106f357600080fd5b5060085461070c9061ffff808216916201000090041682565b6040805161ffff938416815292909116602083015201610227565b34801561073357600080fd5b50600554610213906001600160a01b031681565b34801561075357600080fd5b5061027d610762366004613a5d565b61190e565b34801561077357600080fd5b5061027d610782366004614131565b611c1d565b34801561079357600080fd5b50600054610213906001600160a01b031681565b3480156107b357600080fd5b506102e46107c236600461415f565b600d6020526000908152604090205481565b3480156107e057600080fd5b5061059e60405180604001604052806005815260200164302e302e3160d81b81525081565b6108a5604080516101808101825260008082526020808301829052835160808082018652838252818301849052818601849052606080830185905285870192909252908401839052830182905260a0830182905260c083018290528351808501855282815280820183905260e084015283518085019094528184528301529061010082019081526020016000815260200160008152602001600081525090565b6108af8383611d3a565b60408051610180810182528254815260018301546020808301919091528251608080820185526002808701546001600160401b038082168552600160401b8204811695850195909552600160801b8104851684880152600160c01b90049093166060808401919091529484019190915260038501546001600160a01b0381169484019490945291939291840191600160a01b900460ff169081111561095657610956613890565b600281111561096757610967613890565b8152600382015463ffffffff600160a81b82048116602080850191909152600160c81b909204166040808401919091528051808201825260048501546001600160a01b0390811682526005860154168184015260608401528051808201909152600684015461ffff80821683526201000090910416918101919091526080820152600782015460a0820152600882015460c082015260099091015460e09091015290505b92915050565b610a19611dc6565b6000610a258383611d3a565b905060006003820154600160a01b900460ff166002811115610a4957610a49613890565b14610a675760405163918dffd560e01b815260040160405180910390fd5b600360408051610180810182528354815260018401546020808301919091528251608080820185526002808801546001600160401b038082168552600160401b8204811695850195909552600160801b8104851684880152600160c01b90049093166060808401919091529484019190915260038601546001600160a01b03811694840194909452610bcb93869291840191600160a01b90910460ff1690811115610b1457610b14613890565b6002811115610b2557610b25613890565b8152600382015463ffffffff600160a81b82048116602080850191909152600160c81b909204166040808401919091528051808201825260048501546001600160a01b0390811682526005860154168184015260608401528051808201909152600684015461ffff80821683526201000090910416918101919091526080820152600782015460a0820152600882015460c082015260099091015460e090910152611e13565b6003811115610bdc57610bdc613890565b14610bfa576040516357c4c67760e11b815260040160405180910390fd5b8054600782015410610c9d5760038101805460ff60a01b1916600160a01b17905560405163ffffffff83811691908516907f6f9b154c0ac062517aef6e1c07f343cc2cd4f7b0628a6b59fc4780c675f380a790610c599060019061417c565b60405180910390a3600981015460038201546001600160a01b03166000908152600d602052604081208054909190610c929084906141a0565b90915550610cfd9050565b60038101805463ffffffff80851692908616917f6f9b154c0ac062517aef6e1c07f343cc2cd4f7b0628a6b59fc4780c675f380a79160029160ff60a01b1916600160a01b835b02179055604051610cf4919061417c565b60405180910390a35b505050565b600b6020528260005260406000206020528160005260406000208181548110610d2a57600080fd5b600091825260209091206006909102018054600182015460028301546003840154600485015460059095015460ff90941697509195509350919086565b6000610d71611ea3565b610d79611dc6565b610db1858585856000604051908082528060200260200182016040528015610dab578160200160208202803683370190505b50611efc565b9050610dbc60018055565b949350505050565b6000546001600160a01b03163314610def57604051631dd2188d60e31b815260040160405180910390fd5b610df7612548565b565b610e01611ea3565b6002546001600160a01b03163314610e2c57604051631dd2188d60e31b815260040160405180910390fd5b610e34611dc6565b6000610e408484611d3a565b905060016003820154600160a01b900460ff166002811115610e6457610e64613890565b14610e825760405163693c172160e01b815260040160405180910390fd5b600881018054600090915560038201546001600160a01b031673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeed198101610ecf57610eca6001600160a01b0385168361259d565b610ee3565b610ee36001600160a01b03821685846126b6565b604080516001600160a01b0383811682526020820185905286169163ffffffff80891692908a16917f35307b700c76d4257c04fb9e6d83f2f19c31cd385d63ad10a9c24463f9078a01910160405180910390a4505050610cfd60018055565b6000610ff8610f518484611d3a565b60408051610180810182528254815260018301546020808301919091528251608080820185526002808701546001600160401b038082168552600160401b8204811695850195909552600160801b8104851684880152600160c01b90049093166060808401919091529484019190915260038501546001600160a01b0381169484019490945291939291840191600160a01b900460ff1690811115610b1457610b14613890565b9392505050565b6000611009611ea3565b611011611dc6565b61101e8686868686611efc565b905061102960018055565b95945050505050565b6000546001600160a01b0316331461105d57604051631dd2188d60e31b815260040160405180910390fd5b6001600160a01b0381166110845760405163d92e233d60e01b815260040160405180910390fd5b816763726561746f727360c01b036110a35761109f81612719565b5050565b816770726f6a6563747360c01b036110be5761109f81612782565b816536b4b73a32b960d11b036110d75761109f816127eb565b81673232b83637bcb2b960c11b036110f25761109f81612854565b8165746f6b656e7360d01b0361110b5761109f816128bd565b81680e8ded6cadc82eae8d60bb1b036111275761109f81612926565b60405163580aaaa560e11b8152600481018390526024015b60405180910390fd5b6000546001600160a01b0316331461117357604051631dd2188d60e31b815260040160405180910390fd5b610df761298f565b6002546001600160a01b031633146111a657604051631dd2188d60e31b815260040160405180910390fd5b6111ae611dc6565b60006111ba8585611d3a565b905060006003820154600160a01b900460ff1660028111156111de576111de613890565b146111fc5760405163918dffd560e01b815260040160405180910390fd5b60028101546001600160401b0316421061122957604051630dcc91bf60e11b815260040160405180910390fd5b6007546112409084906001600160a01b03166129d2565b6004810154600582015460408051808201909152600684015461ffff8082168352620100009091041660208201526001600160a01b0392831692909116906112909088908890859085908a612d0a565b61129d8787848488612fd9565b8563ffffffff168763ffffffff167f984867b9d64132b49276b0f22c2c7e5271b9f34f9ffbbce66e0fff3c6ade19ba87876040516112dc92919061427e565b60405180910390a350505050505050565b60606112f98383611d3a565b5063ffffffff8084166000908152600b60209081526040808320938616835292815282822080548451818402810184019095528085529092909184015b828210156113c7576000848152602090206040805160c08101909152600684029091018054829060ff16600181111561137157611371613890565b600181111561138257611382613890565b81526020016001820154815260200160028201548152602001600382015481526020016004820154815260200160058201548152505081526020019060010190611336565b50505050905092915050565b6002546001600160a01b031633146113fe57604051631dd2188d60e31b815260040160405180910390fd5b611406611dc6565b60006114128383611d3a565b905060006003820154600160a01b900460ff16600281111561143657611436613890565b146114545760405163918dffd560e01b815260040160405180910390fd5b60038101805463ffffffff80851692908616917f80142e26cc20a079b1b1a1cc37a4fd124a2acbab475e194d9d98e89d78253e979160029160ff60a01b1916600160a01b83610ce3565b6002546001600160a01b031633146114c957604051631dd2188d60e31b815260040160405180910390fd5b6114d1611dc6565b60006114dd8383611d3a565b905060006003820154600160a01b900460ff16600281111561150157611501613890565b1461151f5760405163918dffd560e01b815260040160405180910390fd5b8054600782015410156115455760405163524908cb60e01b815260040160405180910390fd5b60038101805460ff60a01b1916600160a01b17905560405163ffffffff83811691908516907f5189696184f9acaa77415e92694d0d6702c768c707bdaed95e79b55daa225b0d906115989060019061417c565b60405180910390a3600981015460038201546001600160a01b03166000908152600d6020526040812080549091906115d19084906141a0565b9091555050505050565b6002546000906001600160a01b0316331461160957604051631dd2188d60e31b815260040160405180910390fd5b611611611dc6565b6003546040516313c369ed60e01b815263ffffffff861660048201526001600160a01b03909116906313c369ed90602401602060405180830381865afa15801561165f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611683919061429f565b6116a05760405163c5723b5160e01b815260040160405180910390fd5b6007546116b79084906001600160a01b03166129d2565b63ffffffff8085166000908152600960205260408120805490926116db91166142c1565b91906101000a81548163ffffffff021916908363ffffffff160217905590506000600560009054906101000a90046001600160a01b03166001600160a01b031663775c300c6040518163ffffffff1660e01b81526004016020604051808303816000875af1158015611751573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061177591906142e4565b90506000600560009054906101000a90046001600160a01b03166001600160a01b031663775c300c6040518163ffffffff1660e01b81526004016020604051808303816000875af11580156117ce573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117f291906142e4565b6040805180820190915260085461ffff8082168352620100009091041660208201529091506118299087908590859085908a612d0a565b6118368684848488612fd9565b8563ffffffff167f06dd225790184a3f11d6ae53972cf82bda08fa1819008395c7333ae89ff52e8e8487878686604051611874959493929190614301565b60405180910390a250509392505050565b6000546001600160a01b031633146118b057604051631dd2188d60e31b815260040160405180910390fd5b6118c76118c236839003830183614367565b6131d6565b7fc1553013ae550685b029e7a661173ea8af924daddaf7f24c0f816be7e57fbcc36008826040516118f99291906143c5565b60405180910390a1806008610cfd8282614415565b611916611ea3565b61191e611dc6565b600061192a8585611d3a565b905060026003820154600160a01b900460ff16600281111561194e5761194e613890565b1461196c57604051639d5a06d360e01b815260040160405180910390fd5b63ffffffff8086166000908152600b602090815260408083208885168452909152902054908416106119b15760405163c5723b5160e01b815260040160405180910390fd5b63ffffffff8086166000908152600b60209081526040808320888516845290915281208054919290919086169081106119ec576119ec61445f565b906000526020600020906006020190506000816002015484611a0e9190614475565b82549091506000908190611a2a90600687019060ff1685613271565b91509150611a3c8560080154826132d9565b856008016000828254611a4f919061448c565b9250508190555081856009016000828254611a6a919061448c565b90915550508354600090611a839060ff168b8b8b6132ef565b6006546040516302210ae360e11b8152600481018390529192506001600160a01b03169063044215c690602401602060405180830381865afa158015611acd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611af191906142e4565b604051637a94c56560e11b815233600482015260248101839052604481018990526001600160a01b03919091169063f5298aca90606401600060405180830381600087803b158015611b4257600080fd5b505af1158015611b56573d6000803e3d6000fd5b5050505060038601546001600160a01b031673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeed198101611b9357611b8e338661259d565b611ba7565b611ba76001600160a01b03821633876126b6565b60408051338152602081018a90526001600160a01b0383168183015260608101879052905163ffffffff8b8116928d821692918f16917f7e387576ce0d1070913e97a92030e5ad8b61629213e679b4f91d9a3c1c8bbee79181900360800190a450505050505050611c1760018055565b50505050565b611c25611ea3565b6000546001600160a01b03163314611c5057604051631dd2188d60e31b815260040160405180910390fd5b6001600160a01b0382166000908152600d602052604081205490819003611c8a5760405163334ab3f560e11b815260040160405180910390fd5b6001600160a01b0383166000818152600d602052604081205573eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeed1901611cd657611cd16001600160a01b0383168261259d565b611cea565b611cea6001600160a01b03841683836126b6565b604080516001600160a01b038581168252602082018490528416917f4f1b51dd7a2fcb861aa2670f668be66835c4ee12b4bbbf037e4d0018f39819e4910160405180910390a25061109f60018055565b63ffffffff8083166000908152600960205260408120549091168103611d735760405163c5723b5160e01b815260040160405180910390fd5b5063ffffffff8083166000908152600a602090815260408083208585168452909152812060038101549092600160a81b909104169003610a0b5760405163c5723b5160e01b815260040160405180910390fd5b600054600160a01b900460ff1615610df75760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b604482015260640161113f565b6040810151516000906001600160401b0316421015611e3457506000919050565b8160400151606001516001600160401b0316421115611e5557506003919050565b8160400151604001516001600160401b03164210611e7557506002919050565b8160400151602001516001600160401b0316421115611e9657506000919050565b506001919050565b919050565b600260015403611ef55760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015260640161113f565b6002600155565b600080611f098787611d3a565b905060006003820154600160a01b900460ff166002811115611f2d57611f2d613890565b14611f4b5760405163918dffd560e01b815260040160405180910390fd5b60408051610180810182528254815260018301546020808301919091528251608080820185526002808701546001600160401b038082168552600160401b8204811695850195909552600160801b8104851684880152600160c01b90049093166060808401919091529484019190915260038501546001600160a01b03811694840194909452600093611ff893928692840191600160a01b900460ff1690811115610b1457610b14613890565b9050600081600381111561200e5761200e613890565b0361202c576040516342e34b0b60e11b815260040160405180910390fd5b600381600381111561204057612040613890565b0361205e57604051636fa34bf160e11b815260040160405180910390fd5b63ffffffff8089166000908152600b602090815260408083208b85168452909152902054908716106120a35760405163c5723b5160e01b815260040160405180910390fd5b63ffffffff8089166000908152600b602090815260408083208b8516845290915281208054919290919089169081106120de576120de61445f565b600091825260209091206006909102019050600182600381111561210457612104613890565b148015612152575060048101546040516bffffffffffffffffffffffff193360601b1660208201526121509187916034016040516020818303038152906040528051906020012061337a565b155b15612170576040516309bde33960e01b815260040160405180910390fd5b806001015486826005015461218591906141a0565b11156121a4576040516340d7f6ab60e01b815260040160405180910390fd5b600381015463ffffffff808b166000908152600c602090815260408083208d851684528252808320938c168352928152828220338352905220546121e99088906141a0565b1115612208576040516301d83f5b60e61b815260040160405180910390fd5b600081600201548761221a9190614475565b60038501549091506001600160a01b031673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeed19810161226c5781341461226757604051637e2897ef60e11b815260040160405180910390fd5b612317565b341561228b57604051637e2897ef60e11b815260040160405180910390fd5b600754604051637e4ecb5d60e11b81526001600160a01b0383811660048301529091169063fc9d96ba90602401602060405180830381865afa1580156122d5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122f9919061429f565b1561231757604051631eb3268560e31b815260040160405180910390fd5b600082866007015461232991906141a0565b905085600101546000141580156123435750856001015481115b156123605760405162dceabf60e31b815260040160405180910390fd5b63ffffffff808d166000908152600c602090815260408083208f851684528252808320938e168352928152828220338352905290812080548b92906123a69084906141a0565b92505081905550888460050160008282546123c191906141a0565b909155505060078601819055835460009081906123e69060068a019060ff1687613271565b91509150808860080160008282546123fe91906141a0565b925050819055508188600901600082825461241991906141a0565b90915550506001600160a01b03841673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee14612457576124576001600160a01b038516333088613390565b85546124689060ff168f8f8f6132ef565b6004805460405163731133e960e01b8152339281019290925260248201839052604482018e90526080606483015260006084830152919a506001600160a01b039091169063731133e99060a401600060405180830381600087803b1580156124cf57600080fd5b505af11580156124e3573d6000803e3d6000fd5b505050508b63ffffffff168d63ffffffff168f63ffffffff167f21bf0126253f1a5fdab19623fe2b02a25f1d9aa90582a2097b541d66a87b8f6e338f8f60405161252f9392919061449f565b60405180910390a4505050505050505095945050505050565b6125506133c8565b6000805460ff60a01b191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b6040516001600160a01b03909116815260200160405180910390a1565b804710156125ed5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a20696e73756666696369656e742062616c616e6365000000604482015260640161113f565b6000826001600160a01b03168260405160006040518083038185875af1925050503d806000811461263a576040519150601f19603f3d011682016040523d82523d6000602084013e61263f565b606091505b5050905080610cfd5760405162461bcd60e51b815260206004820152603a60248201527f416464726573733a20756e61626c6520746f2073656e642076616c75652c207260448201527f6563697069656e74206d61792068617665207265766572746564000000000000606482015260840161113f565b6040516001600160a01b038316602482015260448101829052610cfd90849063a9059cbb60e01b906064015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152613418565b600254604080516001600160a01b03928316815291831660208301527f278a10fbe845ad241b4d9c1e0097a1b02b5029cf1f43fabcf7c5b5071bdfd6e9910160405180910390a1600280546001600160a01b0319166001600160a01b0392909216919091179055565b600354604080516001600160a01b03928316815291831660208301527f20038753e1eb1b6f5b62e36364b0cc9d5c98d87c33f7e0887b6d02834c9a75a1910160405180910390a1600380546001600160a01b0319166001600160a01b0392909216919091179055565b600454604080516001600160a01b03928316815291831660208301527fe490d3138e32f1f66ef3971a3c73c7f7704ba0c1d1000f1e2c3df6fc0376610b910160405180910390a1600480546001600160a01b0319166001600160a01b0392909216919091179055565b600554604080516001600160a01b03928316815291831660208301527f5536ce762e2750493749a93a0d6a7b91115bb73d2bd6f45cae892f965fc79e68910160405180910390a1600580546001600160a01b0319166001600160a01b0392909216919091179055565b600654604080516001600160a01b03928316815291831660208301527f68be50e9ea9adbc012cefe148f13d238e819ab9ec1e69d4b2a6140b748479074910160405180910390a1600680546001600160a01b0319166001600160a01b0392909216919091179055565b600754604080516001600160a01b03928316815291831660208301527f358107224b9279a63e7c4bd3dcef4d97b76d0196b8dbbf7dd316bb925bf3e6cc910160405180910390a1600780546001600160a01b0319166001600160a01b0392909216919091179055565b612997611dc6565b6000805460ff60a01b1916600160a01b1790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a2586125803390565b60c08201516001600160a01b031673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee14612aa85760c0820151604051637e4ecb5d60e11b81526001600160a01b0391821660048201529082169063fc9d96ba90602401602060405180830381865afa158015612a46573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a6a919061429f565b15612aa85760405163a1b63ceb60e01b815260206004820152600d60248201526c34b73b30b634b2103a37b5b2b760991b604482015260640161113f565b602082015115612af557815160208301511015612af55760405163a1b63ceb60e01b815260206004820152600a6024820152691b585e080f0819dbd85b60b21b604482015260640161113f565b81604001516001600160401b031682606001516001600160401b03161015612b4e5760405163a1b63ceb60e01b815260206004820152600b60248201526a195b99080f081cdd185c9d60aa1b604482015260640161113f565b81608001516001600160401b03168260a001516001600160401b031611612ba75760405163a1b63ceb60e01b815260206004820152600c60248201526b195b99080f0f481cdd185c9d60a21b604482015260640161113f565b81606001516001600160401b031682608001516001600160401b03161015612c055760405163a1b63ceb60e01b815260206004820152601060248201526f7075626c6963203c2070726573616c6560801b604482015260640161113f565b4282604001516001600160401b03161015612c525760405163a1b63ceb60e01b815260206004820152600c60248201526b7374617274203c3d206e6f7760a01b604482015260640161113f565b6301e1338082604001518360600151612c6b91906144fc565b6001600160401b03161115612cae5760405163a1b63ceb60e01b8152602060048201526008602482015267746f6f206c6f6e6760c01b604482015260640161113f565b6301e1338082608001518360a00151612cc791906144fc565b6001600160401b0316111561109f5760405163a1b63ceb60e01b8152602060048201526008602482015267746f6f206c6f6e6760c01b604482015260640161113f565b6040518061018001604052808260000151815260200182602001518152602001604051806080016040528084604001516001600160401b0316815260200184606001516001600160401b0316815260200184608001516001600160401b031681526020018460a001516001600160401b031681525081526020018260c001516001600160a01b0316815260200160006002811115612daa57612daa613890565b815263ffffffff80891660208084018290529189166040808501829052805180820182526001600160a01b03808c1682528a81168287015260608088019290925260808088018b9052600060a0890181905260c0890181905260e0909801889052948752600a86528287209387529285529481902086518155868501516001820155868201518051600280840180549884015195840151938a01516001600160401b03908116600160c01b026001600160c01b03958216600160801b02959095166fffffffffffffffffffffffffffffffff978216600160401b026fffffffffffffffffffffffffffffffff19909b1691909416179890981794909416171790945593850151600384018054919092166001600160a01b031982168117835592860151939491926001600160a81b03199091161790600160a01b908490811115612ef657612ef6613890565b021790555060a082015160038201805460c085015163ffffffff908116600160c81b0263ffffffff60c81b1991909416600160a81b021667ffffffffffffffff60a81b199091161791909117905560e082015180516004830180546001600160a01b039283166001600160a01b0319918216179091556020928301516005850180549190931691161790556101008301518051600684018054929093015161ffff908116620100000263ffffffff199093169116171790556101208201516007820155610140820151600882015561016090910151600990910155505050505050565b63ffffffff8086166000908152600b602090815260408083209388168352929052908120613006916137ed565b60005b81518110156131ce5760008282815181106130265761302661445f565b60200260200101519050613039816134ea565b63ffffffff8088166000908152600b60209081526040808320938a168352929052819020815160c0810190925282519091908190600181111561307e5761307e613890565b815260208481015181830152604080860151908301526060808601519083015260808086015190830152600060a090920182905283546001818101865594835291208251600690920201805492939092839160ff199091169083818111156130e8576130e8613890565b02179055506020820151816001015560408201518160020155606082015181600301556080820151816004015560a082015181600501555050600061313382600001518989866132ef565b90506000808351600181111561314b5761314b613890565b146131565785613158565b865b60055460405163dbbdf08360e01b8152600481018590526001600160a01b03808416602483015292935091169063dbbdf08390604401600060405180830381600087803b1580156131a857600080fd5b505af11580156131bc573d6000803e3d6000fd5b50505050836001019350505050613009565b505050505050565b612710816000015161ffff16106132215760405163a1b63ceb60e01b815260206004820152600e60248201526d696e76616c69642066616e46656560901b604482015260640161113f565b612710816020015161ffff161061326e5760405163a1b63ceb60e01b815260206004820152601060248201526f696e76616c6964206272616e6446656560801b604482015260640161113f565b50565b600080808085600181111561328857613288613890565b1461329e57855462010000900461ffff166132a5565b855461ffff165b61ffff1690506127106132b88583614475565b6132c29190614523565b92506132ce838561448c565b915050935093915050565b60008183106132e85781610ff8565b5090919050565b60008060405180608001604052808663ffffffff1681526020018563ffffffff1681526020018463ffffffff16815260200187600181111561333357613333613890565b81525090506000604051806060016040528061334e8461356f565b61ffff19168152600060208201819052604090910152905061336f816135ba565b979650505050505050565b60008261338785846135f9565b14949350505050565b6040516001600160a01b0380851660248301528316604482015260648101829052611c179085906323b872dd60e01b906084016126e2565b600054600160a01b900460ff16610df75760405162461bcd60e51b815260206004820152601460248201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b604482015260640161113f565b600061346d826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166136469092919063ffffffff16565b805190915015610cfd578080602001905181019061348b919061429f565b610cfd5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b606482015260840161113f565b806020015160000361352d5760405163a1b63ceb60e01b815260206004820152600b60248201526a7a65726f20737570706c7960a81b604482015260640161113f565b806060015160000361326e5760405163a1b63ceb60e01b815260206004820152600a6024820152691e995c9bc81b1a5b5a5d60b21b604482015260640161113f565b600080600060781b836060015184604001518560200151866000015160405160200161359f959493929190614545565b604051602081830303815290604052905080610ff8906145a8565b6000808260000151836020015184604001516040516020016135de939291906145da565b604051602081830303815290604052905080610ff89061461d565b600081815b845181101561363e5761362a8286838151811061361d5761361d61445f565b6020026020010151613655565b91508061363681614641565b9150506135fe565b509392505050565b6060610dbc8484600085613684565b6000818310613671576000828152602084905260409020610ff8565b6000838152602083905260409020610ff8565b6060824710156136e55760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b606482015260840161113f565b600080866001600160a01b03168587604051613701919061465a565b60006040518083038185875af1925050503d806000811461373e576040519150601f19603f3d011682016040523d82523d6000602084013e613743565b606091505b509150915061336f87838387606083156137be5782516000036137b7576001600160a01b0385163b6137b75760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640161113f565b5081610dbc565b610dbc83838151156137d35781518083602001fd5b8060405162461bcd60e51b815260040161113f9190613f96565b508054600082556006029060005260206000209081019061326e91905b8082111561384557805460ff19168155600060018201819055600282018190556003820181905560048201819055600582015560060161380a565b5090565b803563ffffffff81168114611e9e57600080fd5b6000806040838503121561387057600080fd5b61387983613849565b915061388760208401613849565b90509250929050565b634e487b7160e01b600052602160045260246000fd5b600381106138b6576138b6613890565b9052565b60006102208201905082518252602083015160208301526040830151613911604084018280516001600160401b03908116835260208083015182169084015260408083015182169084015260609182015116910152565b5060608301516001600160a01b031660c0830152608083015161393760e08401826138a6565b5060a08301516101006139518185018363ffffffff169052565b60c0850151915061012061396c8186018463ffffffff169052565b60e086015192506101406139988187018580516001600160a01b03908116835260209182015116910152565b91860151805161ffff908116610180880152602090910151166101a08601528501516101c08501528401516101e084015250610160909201516102009091015290565b6000806000606084860312156139f057600080fd5b6139f984613849565b9250613a0760208501613849565b9150604084013590509250925092565b600281106138b6576138b6613890565b60c08101613a358289613a17565b602082019690965260408101949094526060840192909252608083015260a090910152919050565b60008060008060808587031215613a7357600080fd5b613a7c85613849565b9350613a8a60208601613849565b9250613a9860408601613849565b9396929550929360600135925050565b6001600160a01b038116811461326e57600080fd5b600080600060608486031215613ad257600080fd5b613adb84613849565b9250613ae960208501613849565b91506040840135613af981613aa8565b809150509250925092565b6020810160048310613b1857613b18613890565b91905290565b8c8152602081018c90526102208101613b68604083018d80516001600160401b03908116835260208083015182169084015260408083015182169084015260609182015116910152565b6001600160a01b038b1660c0830152613b8460e083018b6138a6565b63ffffffff9889166101008301529690971661012088015284516001600160a01b0390811661014089015260209586015116610160880152835161ffff90811661018089015293909401519092166101a08601526101c08501526101e08401526102009092019190915295945050505050565b634e487b7160e01b600052604160045260246000fd5b60405160a081016001600160401b0381118282101715613c2f57613c2f613bf7565b60405290565b604051601f8201601f191681016001600160401b0381118282101715613c5d57613c5d613bf7565b604052919050565b60006001600160401b03821115613c7e57613c7e613bf7565b5060051b60200190565b600080600080600060a08688031215613ca057600080fd5b613ca986613849565b94506020613cb8818801613849565b9450613cc660408801613849565b93506060870135925060808701356001600160401b03811115613ce857600080fd5b8701601f81018913613cf957600080fd5b8035613d0c613d0782613c65565b613c35565b81815260059190911b8201830190838101908b831115613d2b57600080fd5b928401925b82841015613d4957833582529284019290840190613d30565b80955050505050509295509295909350565b60008060408385031215613d6e57600080fd5b823591506020830135613d8081613aa8565b809150509250929050565b80356001600160401b0381168114611e9e57600080fd5b600060e08284031215613db457600080fd5b60405160e081018181106001600160401b0382111715613dd657613dd6613bf7565b80604052508091508235815260208301356020820152613df860408401613d8b565b6040820152613e0960608401613d8b565b6060820152613e1a60808401613d8b565b6080820152613e2b60a08401613d8b565b60a082015260c0830135613e3e81613aa8565b60c0919091015292915050565b600082601f830112613e5c57600080fd5b81356020613e6c613d0783613c65565b82815260a09283028501820192828201919087851115613e8b57600080fd5b8387015b85811015613ef45781818a031215613ea75760008081fd5b613eaf613c0d565b813560028110613ebf5760008081fd5b815281860135868201526040808301359082015260608083013590820152608080830135908201528452928401928101613e8f565b5090979650505050505050565b6000806000806101408587031215613f1857600080fd5b613f2185613849565b9350613f2f60208601613849565b9250613f3e8660408701613da2565b91506101208501356001600160401b03811115613f5a57600080fd5b613f6687828801613e4b565b91505092959194509250565b60005b83811015613f8d578181015183820152602001613f75565b50506000910152565b6020815260008251806020840152613fb5816040850160208701613f72565b601f01601f19169190910160400192915050565b60008060008060808587031215613fdf57600080fd5b613fe885613849565b9350613ff660208601613849565b925061400460408601613849565b9150606085013561401481613aa8565b939692955090935050565b602080825282518282018190526000919060409081850190868401855b82811015614091578151614051858251613a17565b80870151858801528581015186860152606080820151908601526080808201519086015260a0908101519085015260c0909301929085019060010161403c565b5091979650505050505050565b6000602082840312156140b057600080fd5b610ff882613849565b600080600061012084860312156140cf57600080fd5b6140d884613849565b92506140e78560208601613da2565b91506101008401356001600160401b0381111561410357600080fd5b61410f86828701613e4b565b9150509250925092565b60006040828403121561412b57600080fd5b50919050565b6000806040838503121561414457600080fd5b823561414f81613aa8565b91506020830135613d8081613aa8565b60006020828403121561417157600080fd5b8135610ff881613aa8565b60208101610a0b82846138a6565b634e487b7160e01b600052601160045260246000fd5b80820180821115610a0b57610a0b61418a565b805182526020810151602083015260408101516001600160401b0380821660408501528060608401511660608501528060808401511660808501528060a08401511660a0850152505060018060a01b0360c08201511660c08301525050565b600081518084526020808501945080840160005b8381101561427357815161423b888251613a17565b808401518885015260408082015190890152606080820151908901526080908101519088015260a09096019590820190600101614226565b509495945050505050565b600061010061428d83866141b3565b8060e084015261102981840185614212565b6000602082840312156142b157600080fd5b81518015158114610ff857600080fd5b600063ffffffff8083168181036142da576142da61418a565b6001019392505050565b6000602082840312156142f657600080fd5b8151610ff881613aa8565b600061016063ffffffff8816835261431c60208401886141b3565b8061010084015261432f81840187614212565b6001600160a01b03958616610120850152939094166101409092019190915250949350505050565b61ffff8116811461326e57600080fd5b60006040828403121561437957600080fd5b604051604081018181106001600160401b038211171561439b5761439b613bf7565b60405282356143a981614357565b815260208301356143b981614357565b60208201529392505050565b825461ffff808216835260109190911c8116602083015260808201908335906143ed82614357565b908116604084015260208401359061440482614357565b808216606085015250509392505050565b813561442081614357565b61ffff8116905081548161ffff198216178355602084013561444181614357565b63ffff00008160101b168363ffffffff198416171784555050505050565b634e487b7160e01b600052603260045260246000fd5b8082028115828204841417610a0b57610a0b61418a565b81810381811115610a0b57610a0b61418a565b6001600160a01b038416815260208082018490526060604083018190528351908301819052600091848101916080850190845b818110156144ee578451835293830193918301916001016144d2565b509098975050505050505050565b6001600160401b0382811682821603908082111561451c5761451c61418a565b5092915050565b60008261454057634e487b7160e01b600052601260045260246000fd5b500490565b6effffffffffffffffffffffffffffff198616815260006002861061456c5761456c613890565b5060f89490941b60118501526001600160e01b031960e093841b8116601286015291831b8216601685015290911b16601a820152601e01919050565b8051602082015161ffff19808216929190601e8310156145d257808184601e0360031b1b83161693505b505050919050565b61ffff198416815260f883901b6001600160f81b031916601e82015260006001831061460857614608613890565b5060f89190911b601f82015260200192915050565b8051602080830151919081101561412b5760001960209190910360031b1b16919050565b6000600182016146535761465361418a565b5060010190565b6000825161466c818460208701613f72565b919091019291505056fea2646970667358221220fb472c756f702f6fe051a2403938964ad6b078fd35725b20ea22a55f61ace26864736f6c6343000811003300000000000000000000000011fbbcf6e33913f22d4763731188df806e7bc8b1
Deployed Bytecode
0x6080604052600436106101ee5760003560e01c80638ee90dca1161010d578063c509b0be116100a0578063e0b0f21c1161006f578063e0b0f21c14610747578063f255527814610767578063f77c479114610787578063faaebd21146107a7578063ffa1ad74146107d457600080fd5b8063c509b0be146106a7578063c7a0152a146106c7578063d478cd57146106e7578063d5f394881461072757600080fd5b8063aae01773116100dc578063aae01773146105f2578063b13a05fd1461061f578063b9468e911461063f578063bd174da81461065f57600080fd5b80638ee90dca1461052c5780639d63848a1461054c578063a3f4df7e1461056c578063a885cf61146105ab57600080fd5b8063515d74d6116101855780637238695e116101545780637238695e146104b75780638456cb59146104d757806384cea36e146104ec5780638b79543c1461050c57600080fd5b8063515d74d6146103275780635964abde146103545780635b5155721461047a5780635c975abb1461048d57600080fd5b806332b91fb6116101c157806332b91fb61461029f5780633e35b137146102d15780633f4ba83a146102f257806344d851521461030757600080fd5b806307546172146101f357806311c5c7da14610230578063251af3521461025d5780632f2fc4161461027f575b600080fd5b3480156101ff57600080fd5b50600454610213906001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b34801561023c57600080fd5b5061025061024b36600461385d565b610805565b60405161022791906138ba565b34801561026957600080fd5b5061027d61027836600461385d565b610a11565b005b34801561028b57600080fd5b50600254610213906001600160a01b031681565b3480156102ab57600080fd5b506102bf6102ba3660046139db565b610d02565b60405161022796959493929190613a27565b6102e46102df366004613a5d565b610d67565b604051908152602001610227565b3480156102fe57600080fd5b5061027d610dc4565b34801561031357600080fd5b5061027d610322366004613abd565b610df9565b34801561033357600080fd5b5061034761034236600461385d565b610f42565b6040516102279190613b04565b34801561036057600080fd5b5061046261036f36600461385d565b600a60209081526000928352604080842082529183529181902080546001820154835160808101855260028401546001600160401b038082168352600160401b8204811683890152600160801b8204811683880152600160c01b90910416606082015260038401548551808701875260048601546001600160a01b03908116825260058701548116828a01528751808901909852600687015461ffff8082168a52620100009091041698880198909852600786015460088701546009909701549598949793969483169560ff600160a01b8504169563ffffffff600160a81b8604811696600160c81b909604169492918c565b6040516102279c9b9a99989796959493929190613b1e565b6102e4610488366004613c88565b610fff565b34801561049957600080fd5b50600054600160a01b900460ff166040519015158152602001610227565b3480156104c357600080fd5b5061027d6104d2366004613d5b565b611032565b3480156104e357600080fd5b5061027d611148565b3480156104f857600080fd5b50600754610213906001600160a01b031681565b34801561051857600080fd5b50600354610213906001600160a01b031681565b34801561053857600080fd5b5061027d610547366004613f01565b61117b565b34801561055857600080fd5b50600654610213906001600160a01b031681565b34801561057857600080fd5b5061059e6040518060400160405280600681526020016552616973657360d01b81525081565b6040516102279190613f96565b3480156105b757600080fd5b506102e46105c6366004613fc9565b600c60209081526000948552604080862082529385528385208152918452828420909152825290205481565b3480156105fe57600080fd5b5061061261060d36600461385d565b6112ed565b604051610227919061401f565b34801561062b57600080fd5b5061027d61063a36600461385d565b6113d3565b34801561064b57600080fd5b5061027d61065a36600461385d565b61149e565b34801561066b57600080fd5b5061069261067a36600461409e565b60096020526000908152604090205463ffffffff1681565b60405163ffffffff9091168152602001610227565b3480156106b357600080fd5b506106926106c23660046140b9565b6115db565b3480156106d357600080fd5b5061027d6106e2366004614119565b611885565b3480156106f357600080fd5b5060085461070c9061ffff808216916201000090041682565b6040805161ffff938416815292909116602083015201610227565b34801561073357600080fd5b50600554610213906001600160a01b031681565b34801561075357600080fd5b5061027d610762366004613a5d565b61190e565b34801561077357600080fd5b5061027d610782366004614131565b611c1d565b34801561079357600080fd5b50600054610213906001600160a01b031681565b3480156107b357600080fd5b506102e46107c236600461415f565b600d6020526000908152604090205481565b3480156107e057600080fd5b5061059e60405180604001604052806005815260200164302e302e3160d81b81525081565b6108a5604080516101808101825260008082526020808301829052835160808082018652838252818301849052818601849052606080830185905285870192909252908401839052830182905260a0830182905260c083018290528351808501855282815280820183905260e084015283518085019094528184528301529061010082019081526020016000815260200160008152602001600081525090565b6108af8383611d3a565b60408051610180810182528254815260018301546020808301919091528251608080820185526002808701546001600160401b038082168552600160401b8204811695850195909552600160801b8104851684880152600160c01b90049093166060808401919091529484019190915260038501546001600160a01b0381169484019490945291939291840191600160a01b900460ff169081111561095657610956613890565b600281111561096757610967613890565b8152600382015463ffffffff600160a81b82048116602080850191909152600160c81b909204166040808401919091528051808201825260048501546001600160a01b0390811682526005860154168184015260608401528051808201909152600684015461ffff80821683526201000090910416918101919091526080820152600782015460a0820152600882015460c082015260099091015460e09091015290505b92915050565b610a19611dc6565b6000610a258383611d3a565b905060006003820154600160a01b900460ff166002811115610a4957610a49613890565b14610a675760405163918dffd560e01b815260040160405180910390fd5b600360408051610180810182528354815260018401546020808301919091528251608080820185526002808801546001600160401b038082168552600160401b8204811695850195909552600160801b8104851684880152600160c01b90049093166060808401919091529484019190915260038601546001600160a01b03811694840194909452610bcb93869291840191600160a01b90910460ff1690811115610b1457610b14613890565b6002811115610b2557610b25613890565b8152600382015463ffffffff600160a81b82048116602080850191909152600160c81b909204166040808401919091528051808201825260048501546001600160a01b0390811682526005860154168184015260608401528051808201909152600684015461ffff80821683526201000090910416918101919091526080820152600782015460a0820152600882015460c082015260099091015460e090910152611e13565b6003811115610bdc57610bdc613890565b14610bfa576040516357c4c67760e11b815260040160405180910390fd5b8054600782015410610c9d5760038101805460ff60a01b1916600160a01b17905560405163ffffffff83811691908516907f6f9b154c0ac062517aef6e1c07f343cc2cd4f7b0628a6b59fc4780c675f380a790610c599060019061417c565b60405180910390a3600981015460038201546001600160a01b03166000908152600d602052604081208054909190610c929084906141a0565b90915550610cfd9050565b60038101805463ffffffff80851692908616917f6f9b154c0ac062517aef6e1c07f343cc2cd4f7b0628a6b59fc4780c675f380a79160029160ff60a01b1916600160a01b835b02179055604051610cf4919061417c565b60405180910390a35b505050565b600b6020528260005260406000206020528160005260406000208181548110610d2a57600080fd5b600091825260209091206006909102018054600182015460028301546003840154600485015460059095015460ff90941697509195509350919086565b6000610d71611ea3565b610d79611dc6565b610db1858585856000604051908082528060200260200182016040528015610dab578160200160208202803683370190505b50611efc565b9050610dbc60018055565b949350505050565b6000546001600160a01b03163314610def57604051631dd2188d60e31b815260040160405180910390fd5b610df7612548565b565b610e01611ea3565b6002546001600160a01b03163314610e2c57604051631dd2188d60e31b815260040160405180910390fd5b610e34611dc6565b6000610e408484611d3a565b905060016003820154600160a01b900460ff166002811115610e6457610e64613890565b14610e825760405163693c172160e01b815260040160405180910390fd5b600881018054600090915560038201546001600160a01b031673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeed198101610ecf57610eca6001600160a01b0385168361259d565b610ee3565b610ee36001600160a01b03821685846126b6565b604080516001600160a01b0383811682526020820185905286169163ffffffff80891692908a16917f35307b700c76d4257c04fb9e6d83f2f19c31cd385d63ad10a9c24463f9078a01910160405180910390a4505050610cfd60018055565b6000610ff8610f518484611d3a565b60408051610180810182528254815260018301546020808301919091528251608080820185526002808701546001600160401b038082168552600160401b8204811695850195909552600160801b8104851684880152600160c01b90049093166060808401919091529484019190915260038501546001600160a01b0381169484019490945291939291840191600160a01b900460ff1690811115610b1457610b14613890565b9392505050565b6000611009611ea3565b611011611dc6565b61101e8686868686611efc565b905061102960018055565b95945050505050565b6000546001600160a01b0316331461105d57604051631dd2188d60e31b815260040160405180910390fd5b6001600160a01b0381166110845760405163d92e233d60e01b815260040160405180910390fd5b816763726561746f727360c01b036110a35761109f81612719565b5050565b816770726f6a6563747360c01b036110be5761109f81612782565b816536b4b73a32b960d11b036110d75761109f816127eb565b81673232b83637bcb2b960c11b036110f25761109f81612854565b8165746f6b656e7360d01b0361110b5761109f816128bd565b81680e8ded6cadc82eae8d60bb1b036111275761109f81612926565b60405163580aaaa560e11b8152600481018390526024015b60405180910390fd5b6000546001600160a01b0316331461117357604051631dd2188d60e31b815260040160405180910390fd5b610df761298f565b6002546001600160a01b031633146111a657604051631dd2188d60e31b815260040160405180910390fd5b6111ae611dc6565b60006111ba8585611d3a565b905060006003820154600160a01b900460ff1660028111156111de576111de613890565b146111fc5760405163918dffd560e01b815260040160405180910390fd5b60028101546001600160401b0316421061122957604051630dcc91bf60e11b815260040160405180910390fd5b6007546112409084906001600160a01b03166129d2565b6004810154600582015460408051808201909152600684015461ffff8082168352620100009091041660208201526001600160a01b0392831692909116906112909088908890859085908a612d0a565b61129d8787848488612fd9565b8563ffffffff168763ffffffff167f984867b9d64132b49276b0f22c2c7e5271b9f34f9ffbbce66e0fff3c6ade19ba87876040516112dc92919061427e565b60405180910390a350505050505050565b60606112f98383611d3a565b5063ffffffff8084166000908152600b60209081526040808320938616835292815282822080548451818402810184019095528085529092909184015b828210156113c7576000848152602090206040805160c08101909152600684029091018054829060ff16600181111561137157611371613890565b600181111561138257611382613890565b81526020016001820154815260200160028201548152602001600382015481526020016004820154815260200160058201548152505081526020019060010190611336565b50505050905092915050565b6002546001600160a01b031633146113fe57604051631dd2188d60e31b815260040160405180910390fd5b611406611dc6565b60006114128383611d3a565b905060006003820154600160a01b900460ff16600281111561143657611436613890565b146114545760405163918dffd560e01b815260040160405180910390fd5b60038101805463ffffffff80851692908616917f80142e26cc20a079b1b1a1cc37a4fd124a2acbab475e194d9d98e89d78253e979160029160ff60a01b1916600160a01b83610ce3565b6002546001600160a01b031633146114c957604051631dd2188d60e31b815260040160405180910390fd5b6114d1611dc6565b60006114dd8383611d3a565b905060006003820154600160a01b900460ff16600281111561150157611501613890565b1461151f5760405163918dffd560e01b815260040160405180910390fd5b8054600782015410156115455760405163524908cb60e01b815260040160405180910390fd5b60038101805460ff60a01b1916600160a01b17905560405163ffffffff83811691908516907f5189696184f9acaa77415e92694d0d6702c768c707bdaed95e79b55daa225b0d906115989060019061417c565b60405180910390a3600981015460038201546001600160a01b03166000908152600d6020526040812080549091906115d19084906141a0565b9091555050505050565b6002546000906001600160a01b0316331461160957604051631dd2188d60e31b815260040160405180910390fd5b611611611dc6565b6003546040516313c369ed60e01b815263ffffffff861660048201526001600160a01b03909116906313c369ed90602401602060405180830381865afa15801561165f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611683919061429f565b6116a05760405163c5723b5160e01b815260040160405180910390fd5b6007546116b79084906001600160a01b03166129d2565b63ffffffff8085166000908152600960205260408120805490926116db91166142c1565b91906101000a81548163ffffffff021916908363ffffffff160217905590506000600560009054906101000a90046001600160a01b03166001600160a01b031663775c300c6040518163ffffffff1660e01b81526004016020604051808303816000875af1158015611751573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061177591906142e4565b90506000600560009054906101000a90046001600160a01b03166001600160a01b031663775c300c6040518163ffffffff1660e01b81526004016020604051808303816000875af11580156117ce573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117f291906142e4565b6040805180820190915260085461ffff8082168352620100009091041660208201529091506118299087908590859085908a612d0a565b6118368684848488612fd9565b8563ffffffff167f06dd225790184a3f11d6ae53972cf82bda08fa1819008395c7333ae89ff52e8e8487878686604051611874959493929190614301565b60405180910390a250509392505050565b6000546001600160a01b031633146118b057604051631dd2188d60e31b815260040160405180910390fd5b6118c76118c236839003830183614367565b6131d6565b7fc1553013ae550685b029e7a661173ea8af924daddaf7f24c0f816be7e57fbcc36008826040516118f99291906143c5565b60405180910390a1806008610cfd8282614415565b611916611ea3565b61191e611dc6565b600061192a8585611d3a565b905060026003820154600160a01b900460ff16600281111561194e5761194e613890565b1461196c57604051639d5a06d360e01b815260040160405180910390fd5b63ffffffff8086166000908152600b602090815260408083208885168452909152902054908416106119b15760405163c5723b5160e01b815260040160405180910390fd5b63ffffffff8086166000908152600b60209081526040808320888516845290915281208054919290919086169081106119ec576119ec61445f565b906000526020600020906006020190506000816002015484611a0e9190614475565b82549091506000908190611a2a90600687019060ff1685613271565b91509150611a3c8560080154826132d9565b856008016000828254611a4f919061448c565b9250508190555081856009016000828254611a6a919061448c565b90915550508354600090611a839060ff168b8b8b6132ef565b6006546040516302210ae360e11b8152600481018390529192506001600160a01b03169063044215c690602401602060405180830381865afa158015611acd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611af191906142e4565b604051637a94c56560e11b815233600482015260248101839052604481018990526001600160a01b03919091169063f5298aca90606401600060405180830381600087803b158015611b4257600080fd5b505af1158015611b56573d6000803e3d6000fd5b5050505060038601546001600160a01b031673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeed198101611b9357611b8e338661259d565b611ba7565b611ba76001600160a01b03821633876126b6565b60408051338152602081018a90526001600160a01b0383168183015260608101879052905163ffffffff8b8116928d821692918f16917f7e387576ce0d1070913e97a92030e5ad8b61629213e679b4f91d9a3c1c8bbee79181900360800190a450505050505050611c1760018055565b50505050565b611c25611ea3565b6000546001600160a01b03163314611c5057604051631dd2188d60e31b815260040160405180910390fd5b6001600160a01b0382166000908152600d602052604081205490819003611c8a5760405163334ab3f560e11b815260040160405180910390fd5b6001600160a01b0383166000818152600d602052604081205573eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeed1901611cd657611cd16001600160a01b0383168261259d565b611cea565b611cea6001600160a01b03841683836126b6565b604080516001600160a01b038581168252602082018490528416917f4f1b51dd7a2fcb861aa2670f668be66835c4ee12b4bbbf037e4d0018f39819e4910160405180910390a25061109f60018055565b63ffffffff8083166000908152600960205260408120549091168103611d735760405163c5723b5160e01b815260040160405180910390fd5b5063ffffffff8083166000908152600a602090815260408083208585168452909152812060038101549092600160a81b909104169003610a0b5760405163c5723b5160e01b815260040160405180910390fd5b600054600160a01b900460ff1615610df75760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b604482015260640161113f565b6040810151516000906001600160401b0316421015611e3457506000919050565b8160400151606001516001600160401b0316421115611e5557506003919050565b8160400151604001516001600160401b03164210611e7557506002919050565b8160400151602001516001600160401b0316421115611e9657506000919050565b506001919050565b919050565b600260015403611ef55760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015260640161113f565b6002600155565b600080611f098787611d3a565b905060006003820154600160a01b900460ff166002811115611f2d57611f2d613890565b14611f4b5760405163918dffd560e01b815260040160405180910390fd5b60408051610180810182528254815260018301546020808301919091528251608080820185526002808701546001600160401b038082168552600160401b8204811695850195909552600160801b8104851684880152600160c01b90049093166060808401919091529484019190915260038501546001600160a01b03811694840194909452600093611ff893928692840191600160a01b900460ff1690811115610b1457610b14613890565b9050600081600381111561200e5761200e613890565b0361202c576040516342e34b0b60e11b815260040160405180910390fd5b600381600381111561204057612040613890565b0361205e57604051636fa34bf160e11b815260040160405180910390fd5b63ffffffff8089166000908152600b602090815260408083208b85168452909152902054908716106120a35760405163c5723b5160e01b815260040160405180910390fd5b63ffffffff8089166000908152600b602090815260408083208b8516845290915281208054919290919089169081106120de576120de61445f565b600091825260209091206006909102019050600182600381111561210457612104613890565b148015612152575060048101546040516bffffffffffffffffffffffff193360601b1660208201526121509187916034016040516020818303038152906040528051906020012061337a565b155b15612170576040516309bde33960e01b815260040160405180910390fd5b806001015486826005015461218591906141a0565b11156121a4576040516340d7f6ab60e01b815260040160405180910390fd5b600381015463ffffffff808b166000908152600c602090815260408083208d851684528252808320938c168352928152828220338352905220546121e99088906141a0565b1115612208576040516301d83f5b60e61b815260040160405180910390fd5b600081600201548761221a9190614475565b60038501549091506001600160a01b031673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeed19810161226c5781341461226757604051637e2897ef60e11b815260040160405180910390fd5b612317565b341561228b57604051637e2897ef60e11b815260040160405180910390fd5b600754604051637e4ecb5d60e11b81526001600160a01b0383811660048301529091169063fc9d96ba90602401602060405180830381865afa1580156122d5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122f9919061429f565b1561231757604051631eb3268560e31b815260040160405180910390fd5b600082866007015461232991906141a0565b905085600101546000141580156123435750856001015481115b156123605760405162dceabf60e31b815260040160405180910390fd5b63ffffffff808d166000908152600c602090815260408083208f851684528252808320938e168352928152828220338352905290812080548b92906123a69084906141a0565b92505081905550888460050160008282546123c191906141a0565b909155505060078601819055835460009081906123e69060068a019060ff1687613271565b91509150808860080160008282546123fe91906141a0565b925050819055508188600901600082825461241991906141a0565b90915550506001600160a01b03841673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee14612457576124576001600160a01b038516333088613390565b85546124689060ff168f8f8f6132ef565b6004805460405163731133e960e01b8152339281019290925260248201839052604482018e90526080606483015260006084830152919a506001600160a01b039091169063731133e99060a401600060405180830381600087803b1580156124cf57600080fd5b505af11580156124e3573d6000803e3d6000fd5b505050508b63ffffffff168d63ffffffff168f63ffffffff167f21bf0126253f1a5fdab19623fe2b02a25f1d9aa90582a2097b541d66a87b8f6e338f8f60405161252f9392919061449f565b60405180910390a4505050505050505095945050505050565b6125506133c8565b6000805460ff60a01b191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b6040516001600160a01b03909116815260200160405180910390a1565b804710156125ed5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a20696e73756666696369656e742062616c616e6365000000604482015260640161113f565b6000826001600160a01b03168260405160006040518083038185875af1925050503d806000811461263a576040519150601f19603f3d011682016040523d82523d6000602084013e61263f565b606091505b5050905080610cfd5760405162461bcd60e51b815260206004820152603a60248201527f416464726573733a20756e61626c6520746f2073656e642076616c75652c207260448201527f6563697069656e74206d61792068617665207265766572746564000000000000606482015260840161113f565b6040516001600160a01b038316602482015260448101829052610cfd90849063a9059cbb60e01b906064015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152613418565b600254604080516001600160a01b03928316815291831660208301527f278a10fbe845ad241b4d9c1e0097a1b02b5029cf1f43fabcf7c5b5071bdfd6e9910160405180910390a1600280546001600160a01b0319166001600160a01b0392909216919091179055565b600354604080516001600160a01b03928316815291831660208301527f20038753e1eb1b6f5b62e36364b0cc9d5c98d87c33f7e0887b6d02834c9a75a1910160405180910390a1600380546001600160a01b0319166001600160a01b0392909216919091179055565b600454604080516001600160a01b03928316815291831660208301527fe490d3138e32f1f66ef3971a3c73c7f7704ba0c1d1000f1e2c3df6fc0376610b910160405180910390a1600480546001600160a01b0319166001600160a01b0392909216919091179055565b600554604080516001600160a01b03928316815291831660208301527f5536ce762e2750493749a93a0d6a7b91115bb73d2bd6f45cae892f965fc79e68910160405180910390a1600580546001600160a01b0319166001600160a01b0392909216919091179055565b600654604080516001600160a01b03928316815291831660208301527f68be50e9ea9adbc012cefe148f13d238e819ab9ec1e69d4b2a6140b748479074910160405180910390a1600680546001600160a01b0319166001600160a01b0392909216919091179055565b600754604080516001600160a01b03928316815291831660208301527f358107224b9279a63e7c4bd3dcef4d97b76d0196b8dbbf7dd316bb925bf3e6cc910160405180910390a1600780546001600160a01b0319166001600160a01b0392909216919091179055565b612997611dc6565b6000805460ff60a01b1916600160a01b1790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a2586125803390565b60c08201516001600160a01b031673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee14612aa85760c0820151604051637e4ecb5d60e11b81526001600160a01b0391821660048201529082169063fc9d96ba90602401602060405180830381865afa158015612a46573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a6a919061429f565b15612aa85760405163a1b63ceb60e01b815260206004820152600d60248201526c34b73b30b634b2103a37b5b2b760991b604482015260640161113f565b602082015115612af557815160208301511015612af55760405163a1b63ceb60e01b815260206004820152600a6024820152691b585e080f0819dbd85b60b21b604482015260640161113f565b81604001516001600160401b031682606001516001600160401b03161015612b4e5760405163a1b63ceb60e01b815260206004820152600b60248201526a195b99080f081cdd185c9d60aa1b604482015260640161113f565b81608001516001600160401b03168260a001516001600160401b031611612ba75760405163a1b63ceb60e01b815260206004820152600c60248201526b195b99080f0f481cdd185c9d60a21b604482015260640161113f565b81606001516001600160401b031682608001516001600160401b03161015612c055760405163a1b63ceb60e01b815260206004820152601060248201526f7075626c6963203c2070726573616c6560801b604482015260640161113f565b4282604001516001600160401b03161015612c525760405163a1b63ceb60e01b815260206004820152600c60248201526b7374617274203c3d206e6f7760a01b604482015260640161113f565b6301e1338082604001518360600151612c6b91906144fc565b6001600160401b03161115612cae5760405163a1b63ceb60e01b8152602060048201526008602482015267746f6f206c6f6e6760c01b604482015260640161113f565b6301e1338082608001518360a00151612cc791906144fc565b6001600160401b0316111561109f5760405163a1b63ceb60e01b8152602060048201526008602482015267746f6f206c6f6e6760c01b604482015260640161113f565b6040518061018001604052808260000151815260200182602001518152602001604051806080016040528084604001516001600160401b0316815260200184606001516001600160401b0316815260200184608001516001600160401b031681526020018460a001516001600160401b031681525081526020018260c001516001600160a01b0316815260200160006002811115612daa57612daa613890565b815263ffffffff80891660208084018290529189166040808501829052805180820182526001600160a01b03808c1682528a81168287015260608088019290925260808088018b9052600060a0890181905260c0890181905260e0909801889052948752600a86528287209387529285529481902086518155868501516001820155868201518051600280840180549884015195840151938a01516001600160401b03908116600160c01b026001600160c01b03958216600160801b02959095166fffffffffffffffffffffffffffffffff978216600160401b026fffffffffffffffffffffffffffffffff19909b1691909416179890981794909416171790945593850151600384018054919092166001600160a01b031982168117835592860151939491926001600160a81b03199091161790600160a01b908490811115612ef657612ef6613890565b021790555060a082015160038201805460c085015163ffffffff908116600160c81b0263ffffffff60c81b1991909416600160a81b021667ffffffffffffffff60a81b199091161791909117905560e082015180516004830180546001600160a01b039283166001600160a01b0319918216179091556020928301516005850180549190931691161790556101008301518051600684018054929093015161ffff908116620100000263ffffffff199093169116171790556101208201516007820155610140820151600882015561016090910151600990910155505050505050565b63ffffffff8086166000908152600b602090815260408083209388168352929052908120613006916137ed565b60005b81518110156131ce5760008282815181106130265761302661445f565b60200260200101519050613039816134ea565b63ffffffff8088166000908152600b60209081526040808320938a168352929052819020815160c0810190925282519091908190600181111561307e5761307e613890565b815260208481015181830152604080860151908301526060808601519083015260808086015190830152600060a090920182905283546001818101865594835291208251600690920201805492939092839160ff199091169083818111156130e8576130e8613890565b02179055506020820151816001015560408201518160020155606082015181600301556080820151816004015560a082015181600501555050600061313382600001518989866132ef565b90506000808351600181111561314b5761314b613890565b146131565785613158565b865b60055460405163dbbdf08360e01b8152600481018590526001600160a01b03808416602483015292935091169063dbbdf08390604401600060405180830381600087803b1580156131a857600080fd5b505af11580156131bc573d6000803e3d6000fd5b50505050836001019350505050613009565b505050505050565b612710816000015161ffff16106132215760405163a1b63ceb60e01b815260206004820152600e60248201526d696e76616c69642066616e46656560901b604482015260640161113f565b612710816020015161ffff161061326e5760405163a1b63ceb60e01b815260206004820152601060248201526f696e76616c6964206272616e6446656560801b604482015260640161113f565b50565b600080808085600181111561328857613288613890565b1461329e57855462010000900461ffff166132a5565b855461ffff165b61ffff1690506127106132b88583614475565b6132c29190614523565b92506132ce838561448c565b915050935093915050565b60008183106132e85781610ff8565b5090919050565b60008060405180608001604052808663ffffffff1681526020018563ffffffff1681526020018463ffffffff16815260200187600181111561333357613333613890565b81525090506000604051806060016040528061334e8461356f565b61ffff19168152600060208201819052604090910152905061336f816135ba565b979650505050505050565b60008261338785846135f9565b14949350505050565b6040516001600160a01b0380851660248301528316604482015260648101829052611c179085906323b872dd60e01b906084016126e2565b600054600160a01b900460ff16610df75760405162461bcd60e51b815260206004820152601460248201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b604482015260640161113f565b600061346d826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166136469092919063ffffffff16565b805190915015610cfd578080602001905181019061348b919061429f565b610cfd5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b606482015260840161113f565b806020015160000361352d5760405163a1b63ceb60e01b815260206004820152600b60248201526a7a65726f20737570706c7960a81b604482015260640161113f565b806060015160000361326e5760405163a1b63ceb60e01b815260206004820152600a6024820152691e995c9bc81b1a5b5a5d60b21b604482015260640161113f565b600080600060781b836060015184604001518560200151866000015160405160200161359f959493929190614545565b604051602081830303815290604052905080610ff8906145a8565b6000808260000151836020015184604001516040516020016135de939291906145da565b604051602081830303815290604052905080610ff89061461d565b600081815b845181101561363e5761362a8286838151811061361d5761361d61445f565b6020026020010151613655565b91508061363681614641565b9150506135fe565b509392505050565b6060610dbc8484600085613684565b6000818310613671576000828152602084905260409020610ff8565b6000838152602083905260409020610ff8565b6060824710156136e55760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b606482015260840161113f565b600080866001600160a01b03168587604051613701919061465a565b60006040518083038185875af1925050503d806000811461373e576040519150601f19603f3d011682016040523d82523d6000602084013e613743565b606091505b509150915061336f87838387606083156137be5782516000036137b7576001600160a01b0385163b6137b75760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640161113f565b5081610dbc565b610dbc83838151156137d35781518083602001fd5b8060405162461bcd60e51b815260040161113f9190613f96565b508054600082556006029060005260206000209081019061326e91905b8082111561384557805460ff19168155600060018201819055600282018190556003820181905560048201819055600582015560060161380a565b5090565b803563ffffffff81168114611e9e57600080fd5b6000806040838503121561387057600080fd5b61387983613849565b915061388760208401613849565b90509250929050565b634e487b7160e01b600052602160045260246000fd5b600381106138b6576138b6613890565b9052565b60006102208201905082518252602083015160208301526040830151613911604084018280516001600160401b03908116835260208083015182169084015260408083015182169084015260609182015116910152565b5060608301516001600160a01b031660c0830152608083015161393760e08401826138a6565b5060a08301516101006139518185018363ffffffff169052565b60c0850151915061012061396c8186018463ffffffff169052565b60e086015192506101406139988187018580516001600160a01b03908116835260209182015116910152565b91860151805161ffff908116610180880152602090910151166101a08601528501516101c08501528401516101e084015250610160909201516102009091015290565b6000806000606084860312156139f057600080fd5b6139f984613849565b9250613a0760208501613849565b9150604084013590509250925092565b600281106138b6576138b6613890565b60c08101613a358289613a17565b602082019690965260408101949094526060840192909252608083015260a090910152919050565b60008060008060808587031215613a7357600080fd5b613a7c85613849565b9350613a8a60208601613849565b9250613a9860408601613849565b9396929550929360600135925050565b6001600160a01b038116811461326e57600080fd5b600080600060608486031215613ad257600080fd5b613adb84613849565b9250613ae960208501613849565b91506040840135613af981613aa8565b809150509250925092565b6020810160048310613b1857613b18613890565b91905290565b8c8152602081018c90526102208101613b68604083018d80516001600160401b03908116835260208083015182169084015260408083015182169084015260609182015116910152565b6001600160a01b038b1660c0830152613b8460e083018b6138a6565b63ffffffff9889166101008301529690971661012088015284516001600160a01b0390811661014089015260209586015116610160880152835161ffff90811661018089015293909401519092166101a08601526101c08501526101e08401526102009092019190915295945050505050565b634e487b7160e01b600052604160045260246000fd5b60405160a081016001600160401b0381118282101715613c2f57613c2f613bf7565b60405290565b604051601f8201601f191681016001600160401b0381118282101715613c5d57613c5d613bf7565b604052919050565b60006001600160401b03821115613c7e57613c7e613bf7565b5060051b60200190565b600080600080600060a08688031215613ca057600080fd5b613ca986613849565b94506020613cb8818801613849565b9450613cc660408801613849565b93506060870135925060808701356001600160401b03811115613ce857600080fd5b8701601f81018913613cf957600080fd5b8035613d0c613d0782613c65565b613c35565b81815260059190911b8201830190838101908b831115613d2b57600080fd5b928401925b82841015613d4957833582529284019290840190613d30565b80955050505050509295509295909350565b60008060408385031215613d6e57600080fd5b823591506020830135613d8081613aa8565b809150509250929050565b80356001600160401b0381168114611e9e57600080fd5b600060e08284031215613db457600080fd5b60405160e081018181106001600160401b0382111715613dd657613dd6613bf7565b80604052508091508235815260208301356020820152613df860408401613d8b565b6040820152613e0960608401613d8b565b6060820152613e1a60808401613d8b565b6080820152613e2b60a08401613d8b565b60a082015260c0830135613e3e81613aa8565b60c0919091015292915050565b600082601f830112613e5c57600080fd5b81356020613e6c613d0783613c65565b82815260a09283028501820192828201919087851115613e8b57600080fd5b8387015b85811015613ef45781818a031215613ea75760008081fd5b613eaf613c0d565b813560028110613ebf5760008081fd5b815281860135868201526040808301359082015260608083013590820152608080830135908201528452928401928101613e8f565b5090979650505050505050565b6000806000806101408587031215613f1857600080fd5b613f2185613849565b9350613f2f60208601613849565b9250613f3e8660408701613da2565b91506101208501356001600160401b03811115613f5a57600080fd5b613f6687828801613e4b565b91505092959194509250565b60005b83811015613f8d578181015183820152602001613f75565b50506000910152565b6020815260008251806020840152613fb5816040850160208701613f72565b601f01601f19169190910160400192915050565b60008060008060808587031215613fdf57600080fd5b613fe885613849565b9350613ff660208601613849565b925061400460408601613849565b9150606085013561401481613aa8565b939692955090935050565b602080825282518282018190526000919060409081850190868401855b82811015614091578151614051858251613a17565b80870151858801528581015186860152606080820151908601526080808201519086015260a0908101519085015260c0909301929085019060010161403c565b5091979650505050505050565b6000602082840312156140b057600080fd5b610ff882613849565b600080600061012084860312156140cf57600080fd5b6140d884613849565b92506140e78560208601613da2565b91506101008401356001600160401b0381111561410357600080fd5b61410f86828701613e4b565b9150509250925092565b60006040828403121561412b57600080fd5b50919050565b6000806040838503121561414457600080fd5b823561414f81613aa8565b91506020830135613d8081613aa8565b60006020828403121561417157600080fd5b8135610ff881613aa8565b60208101610a0b82846138a6565b634e487b7160e01b600052601160045260246000fd5b80820180821115610a0b57610a0b61418a565b805182526020810151602083015260408101516001600160401b0380821660408501528060608401511660608501528060808401511660808501528060a08401511660a0850152505060018060a01b0360c08201511660c08301525050565b600081518084526020808501945080840160005b8381101561427357815161423b888251613a17565b808401518885015260408082015190890152606080820151908901526080908101519088015260a09096019590820190600101614226565b509495945050505050565b600061010061428d83866141b3565b8060e084015261102981840185614212565b6000602082840312156142b157600080fd5b81518015158114610ff857600080fd5b600063ffffffff8083168181036142da576142da61418a565b6001019392505050565b6000602082840312156142f657600080fd5b8151610ff881613aa8565b600061016063ffffffff8816835261431c60208401886141b3565b8061010084015261432f81840187614212565b6001600160a01b03958616610120850152939094166101409092019190915250949350505050565b61ffff8116811461326e57600080fd5b60006040828403121561437957600080fd5b604051604081018181106001600160401b038211171561439b5761439b613bf7565b60405282356143a981614357565b815260208301356143b981614357565b60208201529392505050565b825461ffff808216835260109190911c8116602083015260808201908335906143ed82614357565b908116604084015260208401359061440482614357565b808216606085015250509392505050565b813561442081614357565b61ffff8116905081548161ffff198216178355602084013561444181614357565b63ffff00008160101b168363ffffffff198416171784555050505050565b634e487b7160e01b600052603260045260246000fd5b8082028115828204841417610a0b57610a0b61418a565b81810381811115610a0b57610a0b61418a565b6001600160a01b038416815260208082018490526060604083018190528351908301819052600091848101916080850190845b818110156144ee578451835293830193918301916001016144d2565b509098975050505050505050565b6001600160401b0382811682821603908082111561451c5761451c61418a565b5092915050565b60008261454057634e487b7160e01b600052601260045260246000fd5b500490565b6effffffffffffffffffffffffffffff198616815260006002861061456c5761456c613890565b5060f89490941b60118501526001600160e01b031960e093841b8116601286015291831b8216601685015290911b16601a820152601e01919050565b8051602082015161ffff19808216929190601e8310156145d257808184601e0360031b1b83161693505b505050919050565b61ffff198416815260f883901b6001600160f81b031916601e82015260006001831061460857614608613890565b5060f89190911b601f82015260200192915050565b8051602080830151919081101561412b5760001960209190910360031b1b16919050565b6000600182016146535761465361418a565b5060010190565b6000825161466c818460208701613f72565b919091019291505056fea2646970667358221220fb472c756f702f6fe051a2403938964ad6b078fd35725b20ea22a55f61ace26864736f6c63430008110033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
00000000000000000000000011fbBCF6e33913F22D4763731188Df806e7Bc8B1
-----Decoded View---------------
Arg [0] : _controller (address): 0x11fbBCF6e33913F22D4763731188Df806e7Bc8B1
-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 00000000000000000000000011fbBCF6e33913F22D4763731188Df806e7Bc8B1
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.