Source Code
Overview
ETH Balance
0 ETH
Eth Value
$0.00Latest 1 from a total of 1 transactions
| Transaction Hash |
Method
|
Block
|
From
|
|
To
|
||||
|---|---|---|---|---|---|---|---|---|---|
| Initialize | 23869588 | 80 days ago | IN | 0 ETH | 0.0000533 |
Latest 1 internal transaction
Advanced mode:
| Parent Transaction Hash | Method | Block |
From
|
|
To
|
||
|---|---|---|---|---|---|---|---|
| 0x60806040 | 23869585 | 80 days ago | Contract Creation | 0 ETH |
Loading...
Loading
Loading...
Loading
Cross-Chain Transactions
Loading...
Loading
Contract Name:
CurvePoolBoosterFactory
Compiler Version
v0.8.28+commit.7893614a
Optimization Enabled:
Yes with 200 runs
Other Settings:
paris EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.0;
import { Initializable } from "../utils/Initializable.sol";
import { Strategizable } from "../governance/Strategizable.sol";
import { CurvePoolBoosterPlain } from "./CurvePoolBoosterPlain.sol";
import { ICreateX } from "../interfaces/ICreateX.sol";
import { Initializable } from "../utils/Initializable.sol";
/// @title CurvePoolBoosterFactory
/// @author Origin Protocol
/// @notice Factory contract to create CurvePoolBoosterPlain instances
contract CurvePoolBoosterFactory is Initializable, Strategizable {
/// @notice Address of the CreateX contract
ICreateX public constant CREATEX = ICreateX(0xba5Ed099633D3B313e4D5F7bdc1305d3c28ba5Ed);
event CurvePoolBoosterPlainCreated(address indexed poolBoosterAddress);
/// @notice Initialize the contract. Normally we'd rather have the governor and strategist set in the constructor,
/// but since this contract is deployed by CreateX we need to set them in the initialize function because
/// the constructor's parameters influence the address of the contract when deployed using CreateX.
/// And having different governor and strategist on the same address on different chains would
/// cause issues.
/// @param _governor Address of the governor
/// @param _strategist Address of the strategist
function initialize(address _governor, address _strategist) external initializer {
_setGovernor(_governor);
_setStrategistAddr(_strategist);
}
/// @notice Create a new CurvePoolBoosterPlain instance
/// @param _rewardToken Address of the reward token (OETH or OUSD)
/// @param _gauge Address of the gauge (e.g. Curve OETH/WETH Gauge)
/// @param _feeCollector Address of the fee collector (e.g. MultichainStrategist)
/// @param _fee Fee in FEE_BASE unit payed when managing campaign
/// @param _campaignRemoteManager Address of the campaign remote manager
/// @param _votemarket Address of the votemarket
/// @param _salt A unique number that affects the address of the pool booster created. Note: this number
/// should match the one from `computePoolBoosterAddress` in order for the final deployed address
/// and pre-computed address to match
/// @param _expectedAddress The expected address of the pool booster. This is used to verify that the pool booster
/// was deployed at the expected address, otherwise the transaction batch will revert. If set to 0 then the
/// address verification is skipped.
function createCurvePoolBoosterPlain(
address _rewardToken,
address _gauge,
address _feeCollector,
uint16 _fee,
address _campaignRemoteManager,
address _votemarket,
bytes32 _salt,
address _expectedAddress
) external onlyGovernorOrStrategist returns (address) {
require(governor() != address(0), "Governor not set");
require(strategistAddr != address(0), "Strategist not set");
// salt encoded sender
address senderAddress = address(bytes20(_salt));
// the contract that calls the CreateX should be encoded in the salt to protect against front-running
require(senderAddress == address(this), "Front-run protection failed");
address poolBoosterAddress = CREATEX.deployCreate2(
_salt,
getInitCode(_rewardToken, _gauge)
);
require(
_expectedAddress == address(0) ||
poolBoosterAddress == _expectedAddress,
"Pool booster deployed at unexpected address"
);
CurvePoolBoosterPlain(payable(poolBoosterAddress)).initialize(
governor(),
strategistAddr,
_fee,
_feeCollector,
_campaignRemoteManager,
_votemarket);
emit CurvePoolBoosterPlainCreated(poolBoosterAddress);
return poolBoosterAddress;
}
// get initialisation code contract code + constructor arguments
function getInitCode(
address _rewardToken,
address _gauge
) internal pure returns (bytes memory) {
return abi.encodePacked(
type(CurvePoolBoosterPlain).creationCode,
abi.encode(_rewardToken, _gauge)
);
}
/// @notice Compute the guarded salt for CreateX protections. This version of guarded
/// salt expects that this factory contract is the one doing calls to the CreateX contract.
function _computeGuardedSalt(bytes32 _salt) internal view returns (bytes32) {
return _efficientHash({a: bytes32(uint256(uint160(address(this)))), b: _salt});
}
/**
* @dev Returns the `keccak256` hash of `a` and `b` after concatenation.
* @param a The first 32-byte value to be concatenated and hashed.
* @param b The second 32-byte value to be concatenated and hashed.
* @return hash The 32-byte `keccak256` hash of `a` and `b`.
*/
function _efficientHash(bytes32 a, bytes32 b) internal pure returns (bytes32 hash) {
// solhint-disable-next-line no-inline-assembly
assembly ("memory-safe") {
mstore(0x00, a)
mstore(0x20, b)
hash := keccak256(0x00, 0x40)
}
}
/// @notice Create a new CurvePoolBoosterPlain instance (address computation version)
/// @param _rewardToken Address of the reward token (OETH or OUSD)
/// @param _gauge Address of the gauge (e.g. Curve OETH/WETH Gauge)
/// @param _salt A unique number that affects the address of the pool booster created. Note: this number
/// should match the one from `createCurvePoolBoosterPlain` in order for the final deployed address
/// and pre-computed address to match
function computePoolBoosterAddress(
address _rewardToken,
address _gauge,
bytes32 _salt
) external view returns (address) {
bytes32 guardedSalt = _computeGuardedSalt(_salt);
return CREATEX.computeCreate2Address(
guardedSalt,
keccak256(getInitCode(_rewardToken, _gauge)),
address(CREATEX)
);
}
/**
* @dev Encodes a salt for CreateX by concatenating deployer address (bytes20), cross-chain protection flag (bytes1),
* and the first 11 bytes of the provided salt (most significant bytes). This function is exposed for easier
* operations. For the salt value itself just use the epoch time when the operation is performed.
* @param salt The raw salt as uint256; converted to bytes32, then only the first 11 bytes (MSB) are used.
* @return encodedSalt The resulting 32-byte encoded salt.
*/
function encodeSaltForCreateX(
uint256 salt
) external view returns (bytes32 encodedSalt) {
// prepare encoded salt guarded by this factory address. When the deployer part of the salt is the same as the
// caller of CreateX the salt is re-hashed and thus guarded from front-running.
address deployer = address(this);
// Flag as uint8 (0)
uint8 flag = 0;
// Salt prefix: high 11 bytes (88 bits) shifted to low position
uint256 saltPrefix = uint256(bytes32(salt)) >> 168;
// Precompute parts
uint256 deployerPart = uint256(uint160(deployer)) << 96; // 20 bytes shifted left 96 bits (12 bytes)
uint256 flagPart = uint256(flag) << 88; // 1 byte shifted left 88 bits (11 bytes)
// Concat via nested OR
// solhint-disable-next-line no-inline-assembly
assembly ("memory-safe") {
encodedSalt := or(or(deployerPart, flagPart), saltPrefix)
}
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC20/IERC20.sol)
pragma solidity ^0.8.0;
/**
* @dev Interface of the ERC20 standard as defined in the EIP.
*/
interface IERC20 {
/**
* @dev Returns the amount of tokens in existence.
*/
function totalSupply() external view returns (uint256);
/**
* @dev Returns the amount of tokens owned by `account`.
*/
function balanceOf(address account) external view returns (uint256);
/**
* @dev Moves `amount` tokens from the caller's account to `recipient`.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transfer(address recipient, uint256 amount) external returns (bool);
/**
* @dev Returns the remaining number of tokens that `spender` will be
* allowed to spend on behalf of `owner` through {transferFrom}. This is
* zero by default.
*
* This value changes when {approve} or {transferFrom} are called.
*/
function allowance(address owner, address spender) external view returns (uint256);
/**
* @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* IMPORTANT: Beware that changing an allowance with this method brings the risk
* that someone may use both the old and the new allowance by unfortunate
* transaction ordering. One possible solution to mitigate this race
* condition is to first reduce the spender's allowance to 0 and set the
* desired value afterwards:
* https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
*
* Emits an {Approval} event.
*/
function approve(address spender, uint256 amount) external returns (bool);
/**
* @dev Moves `amount` tokens from `sender` to `recipient` using the
* allowance mechanism. `amount` is then deducted from the caller's
* allowance.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transferFrom(
address sender,
address recipient,
uint256 amount
) external returns (bool);
/**
* @dev Emitted when `value` tokens are moved from one account (`from`) to
* another (`to`).
*
* Note that `value` may be zero.
*/
event Transfer(address indexed from, address indexed to, uint256 value);
/**
* @dev Emitted when the allowance of a `spender` for an `owner` is set by
* a call to {approve}. `value` is the new allowance.
*/
event Approval(address indexed owner, address indexed spender, uint256 value);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC20/utils/SafeERC20.sol)
pragma solidity ^0.8.0;
import "../IERC20.sol";
import "../../../utils/Address.sol";
/**
* @title SafeERC20
* @dev Wrappers around ERC20 operations that throw on failure (when the token
* contract returns false). Tokens that return no value (and instead revert or
* throw on failure) are also supported, non-reverting calls are assumed to be
* successful.
* To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,
* which allows you to call the safe operations as `token.safeTransfer(...)`, etc.
*/
library SafeERC20 {
using Address for address;
function safeTransfer(
IERC20 token,
address to,
uint256 value
) internal {
_callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));
}
function safeTransferFrom(
IERC20 token,
address from,
address to,
uint256 value
) internal {
_callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));
}
/**
* @dev Deprecated. This function has issues similar to the ones found in
* {IERC20-approve}, and its usage is discouraged.
*
* Whenever possible, use {safeIncreaseAllowance} and
* {safeDecreaseAllowance} instead.
*/
function safeApprove(
IERC20 token,
address spender,
uint256 value
) internal {
// safeApprove should only be called when setting an initial allowance,
// or when resetting it to zero. To increase and decrease it, use
// 'safeIncreaseAllowance' and 'safeDecreaseAllowance'
require(
(value == 0) || (token.allowance(address(this), spender) == 0),
"SafeERC20: approve from non-zero to non-zero allowance"
);
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));
}
function safeIncreaseAllowance(
IERC20 token,
address spender,
uint256 value
) internal {
uint256 newAllowance = token.allowance(address(this), spender) + value;
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
}
function safeDecreaseAllowance(
IERC20 token,
address spender,
uint256 value
) internal {
unchecked {
uint256 oldAllowance = token.allowance(address(this), spender);
require(oldAllowance >= value, "SafeERC20: decreased allowance below zero");
uint256 newAllowance = oldAllowance - value;
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
}
}
/**
* @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
* on the return value: the return value is optional (but if data is returned, it must not be false).
* @param token The token targeted by the call.
* @param data The call data (encoded using abi.encode or one of its variants).
*/
function _callOptionalReturn(IERC20 token, bytes memory data) private {
// We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since
// we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that
// the target address contains contract code and also asserts for success in the low-level call.
bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed");
if (returndata.length > 0) {
// Return data is optional
require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed");
}
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/Address.sol)
pragma solidity ^0.8.0;
/**
* @dev Collection of functions related to the address type
*/
library Address {
/**
* @dev Returns true if `account` is a contract.
*
* [IMPORTANT]
* ====
* It is unsafe to assume that an address for which this function returns
* false is an externally-owned account (EOA) and not a contract.
*
* Among others, `isContract` will return false for the following
* types of addresses:
*
* - an externally-owned account
* - a contract in construction
* - an address where a contract will be created
* - an address where a contract lived, but was destroyed
* ====
*/
function isContract(address account) internal view returns (bool) {
// This method relies on extcodesize, which returns 0 for contracts in
// construction, since the code is only stored at the end of the
// constructor execution.
uint256 size;
assembly {
size := extcodesize(account)
}
return size > 0;
}
/**
* @dev Replacement for Solidity's `transfer`: sends `amount` wei to
* `recipient`, forwarding all available gas and reverting on errors.
*
* https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
* of certain opcodes, possibly making contracts go over the 2300 gas limit
* imposed by `transfer`, making them unable to receive funds via
* `transfer`. {sendValue} removes this limitation.
*
* https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].
*
* IMPORTANT: because control is transferred to `recipient`, care must be
* taken to not create reentrancy vulnerabilities. Consider using
* {ReentrancyGuard} or the
* https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
*/
function sendValue(address payable recipient, uint256 amount) internal {
require(address(this).balance >= amount, "Address: insufficient balance");
(bool success, ) = recipient.call{value: amount}("");
require(success, "Address: unable to send value, recipient may have reverted");
}
/**
* @dev Performs a Solidity function call using a low level `call`. A
* plain `call` is an unsafe replacement for a function call: use this
* function instead.
*
* If `target` reverts with a revert reason, it is bubbled up by this
* function (like regular Solidity function calls).
*
* Returns the raw returned data. To convert to the expected return value,
* use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
*
* Requirements:
*
* - `target` must be a contract.
* - calling `target` with `data` must not revert.
*
* _Available since v3.1._
*/
function functionCall(address target, bytes memory data) internal returns (bytes memory) {
return functionCall(target, data, "Address: low-level call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with
* `errorMessage` as a fallback revert reason when `target` reverts.
*
* _Available since v3.1._
*/
function functionCall(
address target,
bytes memory data,
string memory errorMessage
) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but also transferring `value` wei to `target`.
*
* Requirements:
*
* - the calling contract must have an ETH balance of at least `value`.
* - the called Solidity function must be `payable`.
*
* _Available since v3.1._
*/
function functionCallWithValue(
address target,
bytes memory data,
uint256 value
) internal returns (bytes memory) {
return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
}
/**
* @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but
* with `errorMessage` as a fallback revert reason when `target` reverts.
*
* _Available since v3.1._
*/
function functionCallWithValue(
address target,
bytes memory data,
uint256 value,
string memory errorMessage
) internal returns (bytes memory) {
require(address(this).balance >= value, "Address: insufficient balance for call");
require(isContract(target), "Address: call to non-contract");
(bool success, bytes memory returndata) = target.call{value: value}(data);
return verifyCallResult(success, returndata, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but performing a static call.
*
* _Available since v3.3._
*/
function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
return functionStaticCall(target, data, "Address: low-level static call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
* but performing a static call.
*
* _Available since v3.3._
*/
function functionStaticCall(
address target,
bytes memory data,
string memory errorMessage
) internal view returns (bytes memory) {
require(isContract(target), "Address: static call to non-contract");
(bool success, bytes memory returndata) = target.staticcall(data);
return verifyCallResult(success, returndata, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but performing a delegate call.
*
* _Available since v3.4._
*/
function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
return functionDelegateCall(target, data, "Address: low-level delegate call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
* but performing a delegate call.
*
* _Available since v3.4._
*/
function functionDelegateCall(
address target,
bytes memory data,
string memory errorMessage
) internal returns (bytes memory) {
require(isContract(target), "Address: delegate call to non-contract");
(bool success, bytes memory returndata) = target.delegatecall(data);
return verifyCallResult(success, returndata, errorMessage);
}
/**
* @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the
* revert reason using the provided one.
*
* _Available since v4.3._
*/
function verifyCallResult(
bool success,
bytes memory returndata,
string memory errorMessage
) internal pure returns (bytes memory) {
if (success) {
return returndata;
} else {
// Look for revert reason and bubble it up if present
if (returndata.length > 0) {
// The easiest way to bubble the revert reason is using memory via assembly
assembly {
let returndata_size := mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert(errorMessage);
}
}
}
}// SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.0;
/**
* @title Base for contracts that are managed by the Origin Protocol's Governor.
* @dev Copy of the openzeppelin Ownable.sol contract with nomenclature change
* from owner to governor and renounce methods removed. Does not use
* Context.sol like Ownable.sol does for simplification.
* @author Origin Protocol Inc
*/
abstract contract Governable {
// Storage position of the owner and pendingOwner of the contract
// keccak256("OUSD.governor");
bytes32 private constant governorPosition =
0x7bea13895fa79d2831e0a9e28edede30099005a50d652d8957cf8a607ee6ca4a;
// keccak256("OUSD.pending.governor");
bytes32 private constant pendingGovernorPosition =
0x44c4d30b2eaad5130ad70c3ba6972730566f3e6359ab83e800d905c61b1c51db;
// keccak256("OUSD.reentry.status");
bytes32 private constant reentryStatusPosition =
0x53bf423e48ed90e97d02ab0ebab13b2a235a6bfbe9c321847d5c175333ac4535;
// See OpenZeppelin ReentrancyGuard implementation
uint256 constant _NOT_ENTERED = 1;
uint256 constant _ENTERED = 2;
event PendingGovernorshipTransfer(
address indexed previousGovernor,
address indexed newGovernor
);
event GovernorshipTransferred(
address indexed previousGovernor,
address indexed newGovernor
);
/**
* @notice Returns the address of the current Governor.
*/
function governor() public view returns (address) {
return _governor();
}
/**
* @dev Returns the address of the current Governor.
*/
function _governor() internal view returns (address governorOut) {
bytes32 position = governorPosition;
// solhint-disable-next-line no-inline-assembly
assembly {
governorOut := sload(position)
}
}
/**
* @dev Returns the address of the pending Governor.
*/
function _pendingGovernor()
internal
view
returns (address pendingGovernor)
{
bytes32 position = pendingGovernorPosition;
// solhint-disable-next-line no-inline-assembly
assembly {
pendingGovernor := sload(position)
}
}
/**
* @dev Throws if called by any account other than the Governor.
*/
modifier onlyGovernor() {
require(isGovernor(), "Caller is not the Governor");
_;
}
/**
* @notice Returns true if the caller is the current Governor.
*/
function isGovernor() public view returns (bool) {
return msg.sender == _governor();
}
function _setGovernor(address newGovernor) internal {
emit GovernorshipTransferred(_governor(), newGovernor);
bytes32 position = governorPosition;
// solhint-disable-next-line no-inline-assembly
assembly {
sstore(position, newGovernor)
}
}
/**
* @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 make it call a
* `private` function that does the actual work.
*/
modifier nonReentrant() {
bytes32 position = reentryStatusPosition;
uint256 _reentry_status;
// solhint-disable-next-line no-inline-assembly
assembly {
_reentry_status := sload(position)
}
// On the first call to nonReentrant, _notEntered will be true
require(_reentry_status != _ENTERED, "Reentrant call");
// Any calls to nonReentrant after this point will fail
// solhint-disable-next-line no-inline-assembly
assembly {
sstore(position, _ENTERED)
}
_;
// By storing the original value once again, a refund is triggered (see
// https://eips.ethereum.org/EIPS/eip-2200)
// solhint-disable-next-line no-inline-assembly
assembly {
sstore(position, _NOT_ENTERED)
}
}
function _setPendingGovernor(address newGovernor) internal {
bytes32 position = pendingGovernorPosition;
// solhint-disable-next-line no-inline-assembly
assembly {
sstore(position, newGovernor)
}
}
/**
* @notice Transfers Governance of the contract to a new account (`newGovernor`).
* Can only be called by the current Governor. Must be claimed for this to complete
* @param _newGovernor Address of the new Governor
*/
function transferGovernance(address _newGovernor) external onlyGovernor {
_setPendingGovernor(_newGovernor);
emit PendingGovernorshipTransfer(_governor(), _newGovernor);
}
/**
* @notice Claim Governance of the contract to a new account (`newGovernor`).
* Can only be called by the new Governor.
*/
function claimGovernance() external {
require(
msg.sender == _pendingGovernor(),
"Only the pending Governor can complete the claim"
);
_changeGovernor(msg.sender);
}
/**
* @dev Change Governance of the contract to a new account (`newGovernor`).
* @param _newGovernor Address of the new Governor
*/
function _changeGovernor(address _newGovernor) internal {
require(_newGovernor != address(0), "New Governor is address(0)");
_setGovernor(_newGovernor);
}
}// SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.0;
import { Governable } from "./Governable.sol";
contract Strategizable is Governable {
event StrategistUpdated(address _address);
// Address of strategist
address public strategistAddr;
// For future use
uint256[50] private __gap;
/**
* @dev Verifies that the caller is either Governor or Strategist.
*/
modifier onlyGovernorOrStrategist() {
require(
msg.sender == strategistAddr || isGovernor(),
"Caller is not the Strategist or Governor"
);
_;
}
/**
* @dev Set address of Strategist
* @param _address Address of Strategist
*/
function setStrategistAddr(address _address) external onlyGovernor {
_setStrategistAddr(_address);
}
/**
* @dev Set address of Strategist
* @param _address Address of Strategist
*/
function _setStrategistAddr(address _address) internal {
strategistAddr = _address;
emit StrategistUpdated(_address);
}
}// SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.0;
interface ICampaignRemoteManager {
function createCampaign(
CampaignCreationParams memory params,
uint256 destinationChainId,
uint256 additionalGasLimit,
address votemarket
) external payable;
function manageCampaign(
CampaignManagementParams memory params,
uint256 destinationChainId,
uint256 additionalGasLimit,
address votemarket
) external payable;
function closeCampaign(
CampaignClosingParams memory params,
uint256 destinationChainId,
uint256 additionalGasLimit,
address votemarket
) external payable;
struct CampaignCreationParams {
uint256 chainId;
address gauge;
address manager;
address rewardToken;
uint8 numberOfPeriods;
uint256 maxRewardPerVote;
uint256 totalRewardAmount;
address[] addresses;
address hook;
bool isWhitelist;
}
struct CampaignManagementParams {
uint256 campaignId;
address rewardToken;
uint8 numberOfPeriods;
uint256 totalRewardAmount;
uint256 maxRewardPerVote;
}
struct CampaignClosingParams {
uint256 campaignId;
}
}// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity ^0.8.4;
/**
* @title CreateX Factory Interface Definition
* @author pcaversaccio (https://web.archive.org/web/20230921103111/https://pcaversaccio.com/)
* @custom:coauthor Matt Solomon (https://web.archive.org/web/20230921103335/https://mattsolomon.dev/)
*/
interface ICreateX {
/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
/* TYPES */
/*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
struct Values {
uint256 constructorAmount;
uint256 initCallAmount;
}
/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
/* EVENTS */
/*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
event ContractCreation(address indexed newContract, bytes32 indexed salt);
event ContractCreation(address indexed newContract);
event Create3ProxyContractCreation(
address indexed newContract,
bytes32 indexed salt
);
/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
/* CUSTOM ERRORS */
/*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
error FailedContractCreation(address emitter);
error FailedContractInitialisation(address emitter, bytes revertData);
error InvalidSalt(address emitter);
error InvalidNonceValue(address emitter);
error FailedEtherTransfer(address emitter, bytes revertData);
/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
/* CREATE */
/*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
function deployCreate(bytes memory initCode)
external
payable
returns (address newContract);
function deployCreateAndInit(
bytes memory initCode,
bytes memory data,
Values memory values,
address refundAddress
) external payable returns (address newContract);
function deployCreateAndInit(
bytes memory initCode,
bytes memory data,
Values memory values
) external payable returns (address newContract);
function deployCreateClone(address implementation, bytes memory data)
external
payable
returns (address proxy);
function computeCreateAddress(address deployer, uint256 nonce)
external
view
returns (address computedAddress);
function computeCreateAddress(uint256 nonce)
external
view
returns (address computedAddress);
/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
/* CREATE2 */
/*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
function deployCreate2(bytes32 salt, bytes memory initCode)
external
payable
returns (address newContract);
function deployCreate2(bytes memory initCode)
external
payable
returns (address newContract);
function deployCreate2AndInit(
bytes32 salt,
bytes memory initCode,
bytes memory data,
Values memory values,
address refundAddress
) external payable returns (address newContract);
function deployCreate2AndInit(
bytes32 salt,
bytes memory initCode,
bytes memory data,
Values memory values
) external payable returns (address newContract);
function deployCreate2AndInit(
bytes memory initCode,
bytes memory data,
Values memory values,
address refundAddress
) external payable returns (address newContract);
function deployCreate2AndInit(
bytes memory initCode,
bytes memory data,
Values memory values
) external payable returns (address newContract);
function deployCreate2Clone(
bytes32 salt,
address implementation,
bytes memory data
) external payable returns (address proxy);
function deployCreate2Clone(address implementation, bytes memory data)
external
payable
returns (address proxy);
function computeCreate2Address(
bytes32 salt,
bytes32 initCodeHash,
address deployer
) external pure returns (address computedAddress);
function computeCreate2Address(bytes32 salt, bytes32 initCodeHash)
external
view
returns (address computedAddress);
/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
/* CREATE3 */
/*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
function deployCreate3(bytes32 salt, bytes memory initCode)
external
payable
returns (address newContract);
function deployCreate3(bytes memory initCode)
external
payable
returns (address newContract);
function deployCreate3AndInit(
bytes32 salt,
bytes memory initCode,
bytes memory data,
Values memory values,
address refundAddress
) external payable returns (address newContract);
function deployCreate3AndInit(
bytes32 salt,
bytes memory initCode,
bytes memory data,
Values memory values
) external payable returns (address newContract);
function deployCreate3AndInit(
bytes memory initCode,
bytes memory data,
Values memory values,
address refundAddress
) external payable returns (address newContract);
function deployCreate3AndInit(
bytes memory initCode,
bytes memory data,
Values memory values
) external payable returns (address newContract);
function computeCreate3Address(bytes32 salt, address deployer)
external
pure
returns (address computedAddress);
function computeCreate3Address(bytes32 salt)
external
view
returns (address computedAddress);
}// SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.0;
import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import { SafeERC20 } from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import { Initializable } from "../utils/Initializable.sol";
import { Strategizable } from "../governance/Strategizable.sol";
import { ICampaignRemoteManager } from "../interfaces/ICampaignRemoteManager.sol";
/// @title CurvePoolBooster
/// @author Origin Protocol
/// @notice Contract to manage interactions with VotemarketV2 for a dedicated Curve pool/gauge.
contract CurvePoolBooster is Initializable, Strategizable {
using SafeERC20 for IERC20;
////////////////////////////////////////////////////
/// --- CONSTANTS && IMMUTABLES
////////////////////////////////////////////////////
/// @notice Base fee for the contract, 100%
uint16 public constant FEE_BASE = 10_000;
/// @notice Arbitrum where the votemarket is running
uint256 public constant targetChainId = 42161;
/// @notice Address of the gauge to manage
address public immutable gauge;
/// @notice Address of the reward token
address public immutable rewardToken;
////////////////////////////////////////////////////
/// --- STORAGE
////////////////////////////////////////////////////
/// @notice Fee in FEE_BASE unit payed when managing campaign.
uint16 public fee;
/// @notice Address of the fee collector
address public feeCollector;
/// @notice Address of the campaignRemoteManager linked to VotemarketV2
address public campaignRemoteManager;
/// @notice Address of votemarket in L2
address public votemarket;
/// @notice Id of the campaign created
uint256 public campaignId;
////////////////////////////////////////////////////
/// --- EVENTS
////////////////////////////////////////////////////
event FeeUpdated(uint16 newFee);
event FeeCollected(address feeCollector, uint256 feeAmount);
event FeeCollectorUpdated(address newFeeCollector);
event VotemarketUpdated(address newVotemarket);
event CampaignRemoteManagerUpdated(address newCampaignRemoteManager);
event CampaignCreated(
address gauge,
address rewardToken,
uint256 maxRewardPerVote,
uint256 totalRewardAmount
);
event CampaignIdUpdated(uint256 newId);
event CampaignClosed(uint256 campaignId);
event TotalRewardAmountUpdated(uint256 extraTotalRewardAmount);
event NumberOfPeriodsUpdated(uint8 extraNumberOfPeriods);
event RewardPerVoteUpdated(uint256 newMaxRewardPerVote);
event TokensRescued(address token, uint256 amount, address receiver);
////////////////////////////////////////////////////
/// --- CONSTRUCTOR && INITIALIZATION
////////////////////////////////////////////////////
constructor(address _rewardToken, address _gauge) {
rewardToken = _rewardToken;
gauge = _gauge;
// Prevent implementation contract to be governed
_setGovernor(address(0));
}
/// @notice initialize function, to set up initial internal state
/// @param _strategist Address of the strategist
/// @param _fee Fee in FEE_BASE unit payed when managing campaign
/// @param _feeCollector Address of the fee collector
function initialize(
address _strategist,
uint16 _fee,
address _feeCollector,
address _campaignRemoteManager,
address _votemarket
) external onlyGovernor initializer {
_setStrategistAddr(_strategist);
_setFee(_fee);
_setFeeCollector(_feeCollector);
_setCampaignRemoteManager(_campaignRemoteManager);
_setVotemarket(_votemarket);
}
////////////////////////////////////////////////////
/// --- MUTATIVE FUNCTIONS
////////////////////////////////////////////////////
/// @notice Create a new campaign on VotemarketV2
/// @dev This will use all token available in this contract
/// @param numberOfPeriods Duration of the campaign in weeks
/// @param maxRewardPerVote Maximum reward per vote to distribute, to avoid overspending
/// @param blacklist List of addresses to exclude from the campaign
/// @param bridgeFee Fee to pay for the bridge
/// @param additionalGasLimit Additional gas limit for the bridge
function createCampaign(
uint8 numberOfPeriods,
uint256 maxRewardPerVote,
address[] calldata blacklist,
uint256 bridgeFee,
uint256 additionalGasLimit
) external nonReentrant onlyGovernorOrStrategist {
require(campaignId == 0, "Campaign already created");
require(numberOfPeriods > 1, "Invalid number of periods");
require(maxRewardPerVote > 0, "Invalid reward per vote");
// Handle fee (if any)
uint256 balanceSubFee = _handleFee();
// Approve the balanceSubFee to the campaign manager
IERC20(rewardToken).safeApprove(campaignRemoteManager, 0);
IERC20(rewardToken).safeApprove(campaignRemoteManager, balanceSubFee);
// Create a new campaign
ICampaignRemoteManager(campaignRemoteManager).createCampaign{
value: bridgeFee
}(
ICampaignRemoteManager.CampaignCreationParams({
chainId: targetChainId,
gauge: gauge,
manager: address(this),
rewardToken: rewardToken,
numberOfPeriods: numberOfPeriods,
maxRewardPerVote: maxRewardPerVote,
totalRewardAmount: balanceSubFee,
addresses: blacklist,
hook: address(0),
isWhitelist: false
}),
targetChainId,
additionalGasLimit,
votemarket
);
emit CampaignCreated(
gauge,
rewardToken,
maxRewardPerVote,
balanceSubFee
);
}
/// @notice Manage the total reward amount of the campaign
/// @dev This function should be called after the campaign is created
/// @dev This will use all the token available in this contract
/// @param bridgeFee Fee to pay for the bridge
/// @param additionalGasLimit Additional gas limit for the bridge
function manageTotalRewardAmount(
uint256 bridgeFee,
uint256 additionalGasLimit
) external nonReentrant onlyGovernorOrStrategist {
require(campaignId != 0, "Campaign not created");
// Handle fee (if any)
uint256 balanceSubFee = _handleFee();
// Approve the total reward amount to the campaign manager
IERC20(rewardToken).safeApprove(campaignRemoteManager, 0);
IERC20(rewardToken).safeApprove(campaignRemoteManager, balanceSubFee);
// Manage the campaign
// https://github.com/stake-dao/votemarket-v2/blob/main/packages/votemarket/src/Votemarket.sol#L668
ICampaignRemoteManager(campaignRemoteManager).manageCampaign{
value: bridgeFee
}(
ICampaignRemoteManager.CampaignManagementParams({
campaignId: campaignId,
rewardToken: rewardToken,
numberOfPeriods: 0,
totalRewardAmount: balanceSubFee,
maxRewardPerVote: 0
}),
targetChainId,
additionalGasLimit,
votemarket
);
emit TotalRewardAmountUpdated(balanceSubFee);
}
/// @notice Manage the number of periods of the campaign
/// @dev This function should be called after the campaign is created
/// @param extraNumberOfPeriods Number of additional periods (cannot be 0)
/// that will be added to already existing amount of periods.
/// @param bridgeFee Fee to pay for the bridge
/// @param additionalGasLimit Additional gas limit for the bridge
function manageNumberOfPeriods(
uint8 extraNumberOfPeriods,
uint256 bridgeFee,
uint256 additionalGasLimit
) external nonReentrant onlyGovernorOrStrategist {
require(campaignId != 0, "Campaign not created");
require(extraNumberOfPeriods > 0, "Invalid number of periods");
// Manage the campaign
ICampaignRemoteManager(campaignRemoteManager).manageCampaign{
value: bridgeFee
}(
ICampaignRemoteManager.CampaignManagementParams({
campaignId: campaignId,
rewardToken: rewardToken,
numberOfPeriods: extraNumberOfPeriods,
totalRewardAmount: 0,
maxRewardPerVote: 0
}),
targetChainId,
additionalGasLimit,
votemarket
);
emit NumberOfPeriodsUpdated(extraNumberOfPeriods);
}
/// @notice Manage the reward per vote of the campaign
/// @dev This function should be called after the campaign is created
/// @param newMaxRewardPerVote New maximum reward per vote
/// @param bridgeFee Fee to pay for the bridge
/// @param additionalGasLimit Additional gas limit for the bridge
function manageRewardPerVote(
uint256 newMaxRewardPerVote,
uint256 bridgeFee,
uint256 additionalGasLimit
) external nonReentrant onlyGovernorOrStrategist {
require(campaignId != 0, "Campaign not created");
require(newMaxRewardPerVote > 0, "Invalid reward per vote");
// Manage the campaign
ICampaignRemoteManager(campaignRemoteManager).manageCampaign{
value: bridgeFee
}(
ICampaignRemoteManager.CampaignManagementParams({
campaignId: campaignId,
rewardToken: rewardToken,
numberOfPeriods: 0,
totalRewardAmount: 0,
maxRewardPerVote: newMaxRewardPerVote
}),
targetChainId,
additionalGasLimit,
votemarket
);
emit RewardPerVoteUpdated(newMaxRewardPerVote);
}
/// @notice Close the campaign.
/// @dev This function only work on the L2 chain. Not on mainnet.
/// @dev The _campaignId parameter is not related to the campaignId of this contract, allowing greater flexibility.
/// @param _campaignId Id of the campaign to close
// slither-disable-start reentrancy-eth
function closeCampaign(
uint256 _campaignId,
uint256 bridgeFee,
uint256 additionalGasLimit
) external nonReentrant onlyGovernorOrStrategist {
ICampaignRemoteManager(campaignRemoteManager).closeCampaign{
value: bridgeFee
}(
ICampaignRemoteManager.CampaignClosingParams({
campaignId: campaignId
}),
targetChainId,
additionalGasLimit,
votemarket
);
campaignId = 0;
emit CampaignClosed(_campaignId);
}
// slither-disable-end reentrancy-eth
/// @notice calculate the fee amount and transfer it to the feeCollector
/// @return Balance after fee
function _handleFee() internal returns (uint256) {
// Cache current rewardToken balance
uint256 balance = IERC20(rewardToken).balanceOf(address(this));
require(balance > 0, "No reward to manage");
uint256 feeAmount = (balance * fee) / FEE_BASE;
// If there is a fee, transfer it to the feeCollector
if (feeAmount > 0) {
// Transfer the fee to the feeCollector
IERC20(rewardToken).safeTransfer(feeCollector, feeAmount);
emit FeeCollected(feeCollector, feeAmount);
return IERC20(rewardToken).balanceOf(address(this));
}
// Return remaining balance
return balance;
}
////////////////////////////////////////////////////
/// --- GOVERNANCE && OPERATION
////////////////////////////////////////////////////
/// @notice Set the campaign id
/// @dev Only callable by the governor or strategist
/// @param _campaignId New campaign id
function setCampaignId(uint256 _campaignId)
external
onlyGovernorOrStrategist
{
campaignId = _campaignId;
emit CampaignIdUpdated(_campaignId);
}
/// @notice Rescue ETH from the contract
/// @dev Only callable by the governor or strategist
/// @param receiver Address to receive the ETH
function rescueETH(address receiver)
external
nonReentrant
onlyGovernorOrStrategist
{
require(receiver != address(0), "Invalid receiver");
uint256 balance = address(this).balance;
(bool success, ) = receiver.call{ value: balance }("");
require(success, "Transfer failed");
emit TokensRescued(address(0), balance, receiver);
}
/// @notice Rescue ERC20 tokens from the contract
/// @dev Only callable by the governor or strategist
/// @param token Address of the token to rescue
function rescueToken(address token, address receiver)
external
nonReentrant
onlyGovernor
{
require(receiver != address(0), "Invalid receiver");
uint256 balance = IERC20(token).balanceOf(address(this));
IERC20(token).safeTransfer(receiver, balance);
emit TokensRescued(token, balance, receiver);
}
/// @notice Set the fee
/// @dev Only callable by the governor
/// @param _fee New fee
function setFee(uint16 _fee) external onlyGovernor {
_setFee(_fee);
}
/// @notice Internal logic to set the fee
function _setFee(uint16 _fee) internal {
require(_fee <= FEE_BASE / 2, "Fee too high");
fee = _fee;
emit FeeUpdated(_fee);
}
/// @notice Set the fee collector
/// @dev Only callable by the governor
/// @param _feeCollector New fee collector
function setFeeCollector(address _feeCollector) external onlyGovernor {
_setFeeCollector(_feeCollector);
}
/// @notice Internal logic to set the fee collector
function _setFeeCollector(address _feeCollector) internal {
require(_feeCollector != address(0), "Invalid fee collector");
feeCollector = _feeCollector;
emit FeeCollectorUpdated(_feeCollector);
}
/// @notice Set the campaignRemoteManager
/// @param _campaignRemoteManager New campaignRemoteManager address
function setCampaignRemoteManager(address _campaignRemoteManager)
external
onlyGovernor
{
_setCampaignRemoteManager(_campaignRemoteManager);
}
/// @notice Internal logic to set the campaignRemoteManager
/// @param _campaignRemoteManager New campaignRemoteManager address
function _setCampaignRemoteManager(address _campaignRemoteManager)
internal
{
require(
_campaignRemoteManager != address(0),
"Invalid campaignRemoteManager"
);
campaignRemoteManager = _campaignRemoteManager;
emit CampaignRemoteManagerUpdated(_campaignRemoteManager);
}
/// @notice Set the votemarket address
/// @param _votemarket New votemarket address
function setVotemarket(address _votemarket) external onlyGovernor {
_setVotemarket(_votemarket);
}
/// @notice Internal logic to set the votemarket address
function _setVotemarket(address _votemarket) internal {
require(_votemarket != address(0), "Invalid votemarket");
votemarket = _votemarket;
emit VotemarketUpdated(_votemarket);
}
receive() external payable {}
}// SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.0;
import { CurvePoolBooster } from "./CurvePoolBooster.sol";
/// @title CurvePoolBoosterPlain
/// @author Origin Protocol
/// @notice Contract to manage interactions with VotemarketV2 for a dedicated Curve pool/gauge. It differs from the
/// CurvePoolBooster in that it is not proxied.
/// @dev Governor is not set in the constructor so that the same contract can be deployed on the same address on
/// multiple chains. Governor is set in the initialize function.
contract CurvePoolBoosterPlain is CurvePoolBooster {
constructor(address _rewardToken, address _gauge)
CurvePoolBooster(_rewardToken, _gauge)
{
rewardToken = _rewardToken;
gauge = _gauge;
}
/// @notice initialize function, to set up initial internal state
/// @param _strategist Address of the strategist
/// @param _fee Fee in FEE_BASE unit payed when managing campaign
/// @param _feeCollector Address of the fee collector
/// @dev Since this function is initialized in the same transaction as it is created the initialize function
/// doesn't need role protection.
/// Because the governor is only set in the initialisation function the base class initialize can not be
/// called as it is not the governor who is issueing this call.
function initialize(
address _govenor,
address _strategist,
uint16 _fee,
address _feeCollector,
address _campaignRemoteManager,
address _votemarket
) external initializer {
_setStrategistAddr(_strategist);
_setFee(_fee);
_setFeeCollector(_feeCollector);
_setCampaignRemoteManager(_campaignRemoteManager);
_setVotemarket(_votemarket);
// Set the governor to the provided governor
_setGovernor(_govenor);
}
}// SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.0;
/**
* @title Base contract any contracts that need to initialize state after deployment.
* @author Origin Protocol Inc
*/
abstract contract Initializable {
/**
* @dev Indicates that the contract has been initialized.
*/
bool private initialized;
/**
* @dev Indicates that the contract is in the process of being initialized.
*/
bool private initializing;
/**
* @dev Modifier to protect an initializer function from being invoked twice.
*/
modifier initializer() {
require(
initializing || !initialized,
"Initializable: contract is already initialized"
);
bool isTopLevelCall = !initializing;
if (isTopLevelCall) {
initializing = true;
initialized = true;
}
_;
if (isTopLevelCall) {
initializing = false;
}
}
uint256[50] private ______gap;
}{
"evmVersion": "paris",
"metadata": {
"bytecodeHash": "ipfs",
"useLiteralContent": true
},
"optimizer": {
"enabled": true,
"runs": 200
},
"remappings": [],
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"poolBoosterAddress","type":"address"}],"name":"CurvePoolBoosterPlainCreated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousGovernor","type":"address"},{"indexed":true,"internalType":"address","name":"newGovernor","type":"address"}],"name":"GovernorshipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousGovernor","type":"address"},{"indexed":true,"internalType":"address","name":"newGovernor","type":"address"}],"name":"PendingGovernorshipTransfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_address","type":"address"}],"name":"StrategistUpdated","type":"event"},{"inputs":[],"name":"CREATEX","outputs":[{"internalType":"contract ICreateX","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"claimGovernance","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_rewardToken","type":"address"},{"internalType":"address","name":"_gauge","type":"address"},{"internalType":"bytes32","name":"_salt","type":"bytes32"}],"name":"computePoolBoosterAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_rewardToken","type":"address"},{"internalType":"address","name":"_gauge","type":"address"},{"internalType":"address","name":"_feeCollector","type":"address"},{"internalType":"uint16","name":"_fee","type":"uint16"},{"internalType":"address","name":"_campaignRemoteManager","type":"address"},{"internalType":"address","name":"_votemarket","type":"address"},{"internalType":"bytes32","name":"_salt","type":"bytes32"},{"internalType":"address","name":"_expectedAddress","type":"address"}],"name":"createCurvePoolBoosterPlain","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"salt","type":"uint256"}],"name":"encodeSaltForCreateX","outputs":[{"internalType":"bytes32","name":"encodedSalt","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"governor","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_governor","type":"address"},{"internalType":"address","name":"_strategist","type":"address"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"isGovernor","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_address","type":"address"}],"name":"setStrategistAddr","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"strategistAddr","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_newGovernor","type":"address"}],"name":"transferGovernance","outputs":[],"stateMutability":"nonpayable","type":"function"}]Contract Creation Code
6080604052348015600f57600080fd5b506136e68061001f6000396000f3fe608060405234801561001057600080fd5b50600436106100a95760003560e01c8063799a572d11610071578063799a572d1461011657806395b63c1414610129578063a6384c961461013c578063c7af335214610157578063d38bfff41461016f578063f059e3111461018257600080fd5b80630c340a24146100ae578063485cc955146100d3578063570d8e1d146100e85780635d36b190146100fb578063773540b314610103575b600080fd5b6100b66101a9565b6040516001600160a01b0390911681526020015b60405180910390f35b6100e66100e1366004610a71565b6101c6565b005b6033546100b6906001600160a01b031681565b6100e6610292565b6100e6610111366004610aaa565b610338565b6100b6610124366004610ace565b610398565b6100b6610137366004610b0f565b61045c565b6100b673ba5ed099633d3b313e4d5f7bdc1305d3c28ba5ed81565b61015f6107bb565b60405190151581526020016100ca565b6100e661017d366004610aaa565b6107ec565b61019b610190366004610bb6565b60a81c3060601b1790565b6040519081526020016100ca565b60006101c16000805160206136918339815191525490565b905090565b600054610100900460ff16806101df575060005460ff16155b6102475760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084015b60405180910390fd5b600054610100900460ff16158015610269576000805461ffff19166101011790555b610272836108c0565b61027b82610927565b801561028d576000805461ff00191690555b505050565b7f44c4d30b2eaad5130ad70c3ba6972730566f3e6359ab83e800d905c61b1c51db546001600160a01b0316336001600160a01b03161461032d5760405162461bcd60e51b815260206004820152603060248201527f4f6e6c79207468652070656e64696e6720476f7665726e6f722063616e20636f60448201526f6d706c6574652074686520636c61696d60801b606482015260840161023e565b6103363361097b565b565b6103406107bb565b61038c5760405162461bcd60e51b815260206004820152601a60248201527f43616c6c6572206973206e6f742074686520476f7665726e6f72000000000000604482015260640161023e565b61039581610927565b50565b30600090815260208290526040812073ba5ed099633d3b313e4d5f7bdc1305d3c28ba5ed63d323826a826103cc88886109da565b80516020909101206040516001600160e01b031960e085901b1681526004810192909252602482015273ba5ed099633d3b313e4d5f7bdc1305d3c28ba5ed6044820152606401602060405180830381865afa15801561042f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104539190610bcf565b95945050505050565b6033546000906001600160a01b031633148061047b575061047b6107bb565b6104d85760405162461bcd60e51b815260206004820152602860248201527f43616c6c6572206973206e6f74207468652053747261746567697374206f722060448201526723b7bb32b93737b960c11b606482015260840161023e565b60006104e26101a9565b6001600160a01b03160361052b5760405162461bcd60e51b815260206004820152601060248201526f11dbdd995c9b9bdc881b9bdd081cd95d60821b604482015260640161023e565b6033546001600160a01b03166105785760405162461bcd60e51b815260206004820152601260248201527114dd1c985d1959da5cdd081b9bdd081cd95d60721b604482015260640161023e565b606083901c3081146105cc5760405162461bcd60e51b815260206004820152601b60248201527f46726f6e742d72756e2070726f74656374696f6e206661696c65640000000000604482015260640161023e565b600073ba5ed099633d3b313e4d5f7bdc1305d3c28ba5ed6326307668866105f38e8e6109da565b6040518363ffffffff1660e01b8152600401610610929190610c10565b6020604051808303816000875af115801561062f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106539190610bcf565b90506001600160a01b038416158061067c5750836001600160a01b0316816001600160a01b0316145b6106dc5760405162461bcd60e51b815260206004820152602b60248201527f506f6f6c20626f6f73746572206465706c6f79656420617420756e657870656360448201526a746564206164647265737360a81b606482015260840161023e565b806001600160a01b031663f87bc4346106f36101a9565b60335460405160e084901b6001600160e01b03191681526001600160a01b039283166004820152908216602482015261ffff8c1660448201528c821660648201528a8216608482015290891660a482015260c401600060405180830381600087803b15801561076157600080fd5b505af1158015610775573d6000803e3d6000fd5b50506040516001600160a01b03841692507f29517452b3d8f353a0d81b89ef1eb2c73ce0fc391e9d8e46c2c11c068d73bbe59150600090a29a9950505050505050505050565b60006107d36000805160206136918339815191525490565b6001600160a01b0316336001600160a01b031614905090565b6107f46107bb565b6108405760405162461bcd60e51b815260206004820152601a60248201527f43616c6c6572206973206e6f742074686520476f7665726e6f72000000000000604482015260640161023e565b610868817f44c4d30b2eaad5130ad70c3ba6972730566f3e6359ab83e800d905c61b1c51db55565b806001600160a01b03166108886000805160206136918339815191525490565b6001600160a01b03167fa39cc5eb22d0f34d8beaefee8a3f17cc229c1a1d1ef87a5ad47313487b1c4f0d60405160405180910390a350565b806001600160a01b03166108e06000805160206136918339815191525490565b6001600160a01b03167fc7c0c772add429241571afb3805861fb3cfa2af374534088b76cdb4325a87e9a60405160405180910390a360008051602061369183398151915255565b603380546001600160a01b0319166001600160a01b0383169081179091556040519081527f869e0abd13cc3a975de7b93be3df1cb2255c802b1cead85963cc79d99f131bee9060200160405180910390a150565b6001600160a01b0381166109d15760405162461bcd60e51b815260206004820152601a60248201527f4e657720476f7665726e6f722069732061646472657373283029000000000000604482015260640161023e565b610395816108c0565b6060604051806020016109ec90610a4f565b601f1982820381018352601f9091011660408181526001600160a01b03868116602084015285169082015260600160408051601f1981840301815290829052610a389291602001610c4a565b604051602081830303815290604052905092915050565b612a1780610c7a83390190565b6001600160a01b038116811461039557600080fd5b60008060408385031215610a8457600080fd5b8235610a8f81610a5c565b91506020830135610a9f81610a5c565b809150509250929050565b600060208284031215610abc57600080fd5b8135610ac781610a5c565b9392505050565b600080600060608486031215610ae357600080fd5b8335610aee81610a5c565b92506020840135610afe81610a5c565b929592945050506040919091013590565b600080600080600080600080610100898b031215610b2c57600080fd5b8835610b3781610a5c565b97506020890135610b4781610a5c565b96506040890135610b5781610a5c565b9550606089013561ffff81168114610b6e57600080fd5b94506080890135610b7e81610a5c565b935060a0890135610b8e81610a5c565b925060c0890135915060e0890135610ba581610a5c565b809150509295985092959890939650565b600060208284031215610bc857600080fd5b5035919050565b600060208284031215610be157600080fd5b8151610ac781610a5c565b60005b83811015610c07578181015183820152602001610bef565b50506000910152565b8281526040602082015260008251806040840152610c35816060850160208701610bec565b601f01601f1916919091016060019392505050565b60008351610c5c818460208801610bec565b835190830190610c70818360208801610bec565b0194935050505056fe60c060405234801561001057600080fd5b50604051612a17380380612a1783398101604081905261002f916100ea565b6001600160a01b0380831660a0528116608052818161004e6000610067565b50506001600160a01b0391821660a0521660805261011d565b6001600160a01b0381166100876000805160206129f78339815191525490565b6001600160a01b03167fc7c0c772add429241571afb3805861fb3cfa2af374534088b76cdb4325a87e9a60405160405180910390a36000805160206129f783398151915255565b80516001600160a01b03811681146100e557600080fd5b919050565b600080604083850312156100fd57600080fd5b610106836100ce565b9150610114602084016100ce565b90509250929050565b60805160a0516128536101a46000396000818161056a0152818161087b01528181610d7301528181610dae01528181610df3015281816111310152818161116c0152818161120e015281816113270152818161165d0152818161195b01528181611a490152611ad80152600081816103e7015281816111d0015261130201526128536000f3fe6080604052600436106101c65760003560e01c806394095c2d116100f7578063c7af335211610095578063e9a0214311610064578063e9a0214314610522578063ecefc70514610542578063f7c618c114610558578063f87bc4341461058c57600080fd5b8063c7af33521461048f578063d38bfff4146104b4578063d4629800146104d4578063ddca3f43146104f457600080fd5b8063ab34884c116100d1578063ab34884c14610409578063b0c5b7d814610429578063bcfb252c14610449578063c415b95c1461046957600080fd5b806394095c2d14610395578063a42dce80146103b5578063a6f19c84146103d557600080fd5b8063570d8e1d11610164578063773540b31161013e578063773540b31461031f578063833f68c81461033f5780638e0055531461035f5780638ed5b0fc1461037f57600080fd5b8063570d8e1d146102ca5780635d36b190146102ea5780637039e002146102ff57600080fd5b80630c340a24116101a05780630c340a2414610234578063146ffb261461026657806314c89e171461028a5780634707d000146102aa57600080fd5b806304824e70146101d257806305f56809146101f45780630aaef8541461021457600080fd5b366101cd57005b600080fd5b3480156101de57600080fd5b506101f26101ed36600461216b565b6105ac565b005b34801561020057600080fd5b506101f261020f36600461216b565b610755565b34801561022057600080fd5b506101f261022f366004612186565b610785565b34801561024057600080fd5b5061024961095b565b6040516001600160a01b0390911681526020015b60405180910390f35b34801561027257600080fd5b5061027c61a4b181565b60405190815260200161025d565b34801561029657600080fd5b506101f26102a5366004612186565b610978565b3480156102b657600080fd5b506101f26102c53660046121b2565b610aa2565b3480156102d657600080fd5b50603354610249906001600160a01b031681565b3480156102f657600080fd5b506101f2610c1f565b34801561030b57600080fd5b506101f261031a3660046121e5565b610cc5565b34801561032b57600080fd5b506101f261033a36600461216b565b610ec1565b34801561034b57600080fd5b50606754610249906001600160a01b031681565b34801561036b57600080fd5b506101f261037a366004612219565b610eee565b34801561038b57600080fd5b5061027c60695481565b3480156103a157600080fd5b506101f26103b0366004612234565b610f1b565b3480156103c157600080fd5b506101f26103d036600461216b565b610f8f565b3480156103e157600080fd5b506102497f000000000000000000000000000000000000000000000000000000000000000081565b34801561041557600080fd5b506101f261042436600461225e565b610fbc565b34801561043557600080fd5b506101f26104443660046122fd565b61139e565b34801561045557600080fd5b506101f261046436600461216b565b611460565b34801561047557600080fd5b50606654610249906201000090046001600160a01b031681565b34801561049b57600080fd5b506104a461148d565b604051901515815260200161025d565b3480156104c057600080fd5b506101f26104cf36600461216b565b6114be565b3480156104e057600080fd5b50606854610249906001600160a01b031681565b34801561050057600080fd5b5060665461050f9061ffff1681565b60405161ffff909116815260200161025d565b34801561052e57600080fd5b506101f261053d366004612362565b611562565b34801561054e57600080fd5b5061050f61271081565b34801561056457600080fd5b506102497f000000000000000000000000000000000000000000000000000000000000000081565b34801561059857600080fd5b506101f26105a7366004612395565b611731565b6000805160206127de833981519152805460011981016105e75760405162461bcd60e51b81526004016105de90612409565b60405180910390fd5b600282556033546001600160a01b0316331480610607575061060761148d565b6106235760405162461bcd60e51b81526004016105de90612431565b6001600160a01b03831661066c5760405162461bcd60e51b815260206004820152601060248201526f24b73b30b634b2103932b1b2b4bb32b960811b60448201526064016105de565b60405147906000906001600160a01b0386169083908381818185875af1925050503d80600081146106b9576040519150601f19603f3d011682016040523d82523d6000602084013e6106be565b606091505b50509050806107015760405162461bcd60e51b815260206004820152600f60248201526e151c985b9cd9995c8819985a5b1959608a1b60448201526064016105de565b6040805160008152602081018490526001600160a01b0387168183015290517ffb475a842bad10d3800b61bd1a92e716051afba979b124b583bd99a2d1d7bfd59181900360600190a1505060018255505050565b61075d61148d565b6107795760405162461bcd60e51b81526004016105de90612479565b610782816117d9565b50565b6000805160206127de833981519152805460011981016107b75760405162461bcd60e51b81526004016105de90612409565b600282556033546001600160a01b03163314806107d757506107d761148d565b6107f35760405162461bcd60e51b81526004016105de90612431565b6069546000036108155760405162461bcd60e51b81526004016105de906124b0565b6000851161085f5760405162461bcd60e51b8152602060048201526017602482015276496e76616c6964207265776172642070657220766f746560481b60448201526064016105de565b6067546040805160a08101825260695481526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000081166020830152600082840181905260608301526080820189905260685492516335c5ecd560e21b81529381169363d717b3549389936108e693909261a4b1928b9216906004016124de565b6000604051808303818588803b1580156108ff57600080fd5b505af1158015610913573d6000803e3d6000fd5b50505050507f8f283dbedfa7a1926a86469a652c5f13e8f038708d78cbeb0e1950c9e08625028560405161094991815260200190565b60405180910390a15060019055505050565b60006109736000805160206127fe8339815191525490565b905090565b6000805160206127de833981519152805460011981016109aa5760405162461bcd60e51b81526004016105de90612409565b600282556033546001600160a01b03163314806109ca57506109ca61148d565b6109e65760405162461bcd60e51b81526004016105de90612431565b606754604080516020810182526069548152606854915163c533f30560e01b81529051600482015261a4b16024820152604481018690526001600160a01b03918216606482015291169063c533f3059086906084016000604051808303818588803b158015610a5457600080fd5b505af1158015610a68573d6000803e3d6000fd5b5050600060695550506040518681527f5e6eb33a418de5dbbc17f989f7ae362cdfbb1748c5d603137c767027a354edbc9150602001610949565b6000805160206127de83398151915280546001198101610ad45760405162461bcd60e51b81526004016105de90612409565b60028255610ae061148d565b610afc5760405162461bcd60e51b81526004016105de90612479565b6001600160a01b038316610b455760405162461bcd60e51b815260206004820152601060248201526f24b73b30b634b2103932b1b2b4bb32b960811b60448201526064016105de565b6040516370a0823160e01b81523060048201526000906001600160a01b038616906370a0823190602401602060405180830381865afa158015610b8c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bb0919061253d565b9050610bc66001600160a01b0386168583611872565b604080516001600160a01b038088168252602082018490528616918101919091527ffb475a842bad10d3800b61bd1a92e716051afba979b124b583bd99a2d1d7bfd5906060015b60405180910390a15050600190555050565b7f44c4d30b2eaad5130ad70c3ba6972730566f3e6359ab83e800d905c61b1c51db546001600160a01b0316336001600160a01b031614610cba5760405162461bcd60e51b815260206004820152603060248201527f4f6e6c79207468652070656e64696e6720476f7665726e6f722063616e20636f60448201526f6d706c6574652074686520636c61696d60801b60648201526084016105de565b610cc3336118da565b565b6000805160206127de83398151915280546001198101610cf75760405162461bcd60e51b81526004016105de90612409565b600282556033546001600160a01b0316331480610d175750610d1761148d565b610d335760405162461bcd60e51b81526004016105de90612431565b606954600003610d555760405162461bcd60e51b81526004016105de906124b0565b6000610d5f611939565b606754909150610d9d906001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811691166000611b58565b606754610dd7906001600160a01b037f00000000000000000000000000000000000000000000000000000000000000008116911683611b58565b6067546040805160a08101825260695481526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000081166020830152600082840181905260608301869052608083015260685492516335c5ecd560e21b81529381169363d717b354938a93610e5e93909261a4b1928c9216906004016124de565b6000604051808303818588803b158015610e7757600080fd5b505af1158015610e8b573d6000803e3d6000fd5b50505050507fd922add93b22e9295e2ea259b37756ee2ccafa6872cccda342584d40c754c76681604051610c0d91815260200190565b610ec961148d565b610ee55760405162461bcd60e51b81526004016105de90612479565b61078281611c6d565b610ef661148d565b610f125760405162461bcd60e51b81526004016105de90612479565b61078281611cbb565b6033546001600160a01b0316331480610f375750610f3761148d565b610f535760405162461bcd60e51b81526004016105de90612431565b60698190556040518181527f53c4764ec903d5e515c69c93f0b9b2916f9aa3fa54b34caeeae7bb596d7ec0f6906020015b60405180910390a150565b610f9761148d565b610fb35760405162461bcd60e51b81526004016105de90612479565b61078281611d52565b6000805160206127de83398151915280546001198101610fee5760405162461bcd60e51b81526004016105de90612409565b600282556033546001600160a01b031633148061100e575061100e61148d565b61102a5760405162461bcd60e51b81526004016105de90612431565b6069541561107a5760405162461bcd60e51b815260206004820152601860248201527f43616d706169676e20616c72656164792063726561746564000000000000000060448201526064016105de565b60018860ff16116110c95760405162461bcd60e51b8152602060048201526019602482015278496e76616c6964206e756d626572206f6620706572696f647360381b60448201526064016105de565b600087116111135760405162461bcd60e51b8152602060048201526017602482015276496e76616c6964207265776172642070657220766f746560481b60448201526064016105de565b600061111d611939565b60675490915061115b906001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811691166000611b58565b606754611195906001600160a01b037f00000000000000000000000000000000000000000000000000000000000000008116911683611b58565b606760009054906101000a90046001600160a01b03166001600160a01b0316636509497d8660405180610140016040528061a4b181526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602001306001600160a01b031681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031681526020018d60ff1681526020018c81526020018581526020018b8b8080602002602001604051908101604052809392919081815260200183836020028082843760009201829052509385525050506020820181905260409182015260685490516001600160e01b031960e086901b1681526112c5929161a4b1918b916001600160a01b03169060040161259b565b6000604051808303818588803b1580156112de57600080fd5b505af11580156112f2573d6000803e3d6000fd5b5050604080516001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811682527f00000000000000000000000000000000000000000000000000000000000000001660208201529081018c9052606081018590527ffe76983af97e70cb1d5a3f3b21250c6bd2b5b9216dd3829a1cdab060e17ab15b935060800191506113889050565b60405180910390a1505060019055505050505050565b6113a661148d565b6113c25760405162461bcd60e51b81526004016105de90612479565b600054610100900460ff16806113db575060005460ff16155b6113f75760405162461bcd60e51b81526004016105de90612681565b600054610100900460ff16158015611419576000805461ffff19166101011790555b61142286611c6d565b61142b85611cbb565b61143484611d52565b61143d83611df8565b611446826117d9565b8015611458576000805461ff00191690555b505050505050565b61146861148d565b6114845760405162461bcd60e51b81526004016105de90612479565b61078281611df8565b60006114a56000805160206127fe8339815191525490565b6001600160a01b0316336001600160a01b031614905090565b6114c661148d565b6114e25760405162461bcd60e51b81526004016105de90612479565b61150a817f44c4d30b2eaad5130ad70c3ba6972730566f3e6359ab83e800d905c61b1c51db55565b806001600160a01b031661152a6000805160206127fe8339815191525490565b6001600160a01b03167fa39cc5eb22d0f34d8beaefee8a3f17cc229c1a1d1ef87a5ad47313487b1c4f0d60405160405180910390a350565b6000805160206127de833981519152805460011981016115945760405162461bcd60e51b81526004016105de90612409565b600282556033546001600160a01b03163314806115b457506115b461148d565b6115d05760405162461bcd60e51b81526004016105de90612431565b6069546000036115f25760405162461bcd60e51b81526004016105de906124b0565b60008560ff16116116415760405162461bcd60e51b8152602060048201526019602482015278496e76616c6964206e756d626572206f6620706572696f647360381b60448201526064016105de565b6067546040805160a08101825260695481526001600160a01b037f00000000000000000000000000000000000000000000000000000000000000008116602083015260ff891682840152600060608301819052608083015260685492516335c5ecd560e21b81529381169363d717b3549389936116ca93909261a4b1928b9216906004016124de565b6000604051808303818588803b1580156116e357600080fd5b505af11580156116f7573d6000803e3d6000fd5b505060405160ff891681527f71113ae8f52afc8062af1d0ec71513000c9a7b93eeb737ab8fb50f908445d78a935060200191506109499050565b600054610100900460ff168061174a575060005460ff16155b6117665760405162461bcd60e51b81526004016105de90612681565b600054610100900460ff16158015611788576000805461ffff19166101011790555b61179186611c6d565b61179a85611cbb565b6117a384611d52565b6117ac83611df8565b6117b5826117d9565b6117be87611e9c565b80156117d0576000805461ff00191690555b50505050505050565b6001600160a01b0381166118245760405162461bcd60e51b8152602060048201526012602482015271125b9d985b1a59081d9bdd195b585c9ad95d60721b60448201526064016105de565b606880546001600160a01b0319166001600160a01b0383169081179091556040519081527f4d91cd42ff82ea2004fe60a13788b0c4a8ea5cc08105cc9e21098a93547845ec90602001610f84565b6040516001600160a01b0383166024820152604481018290526118d590849063a9059cbb60e01b906064015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152611f03565b505050565b6001600160a01b0381166119305760405162461bcd60e51b815260206004820152601a60248201527f4e657720476f7665726e6f72206973206164647265737328302900000000000060448201526064016105de565b61078281611e9c565b6040516370a0823160e01b815230600482015260009081906001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906370a0823190602401602060405180830381865afa1580156119a2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119c6919061253d565b905060008111611a0e5760405162461bcd60e51b81526020600482015260136024820152724e6f2072657761726420746f206d616e61676560681b60448201526064016105de565b60665460009061271090611a269061ffff16846126cf565b611a309190612710565b90508015611b5257606654611a78906001600160a01b037f00000000000000000000000000000000000000000000000000000000000000008116916201000090041683611872565b60665460408051620100009092046001600160a01b03168252602082018390527f06c5efeff5c320943d265dc4e5f1af95ad523555ce0c1957e367dda5514572df910160405180910390a16040516370a0823160e01b81523060048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa158015611b27573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b4b919061253d565b9250505090565b50919050565b801580611bd25750604051636eb1769f60e11b81523060048201526001600160a01b03838116602483015284169063dd62ed3e90604401602060405180830381865afa158015611bac573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611bd0919061253d565b155b611c3d5760405162461bcd60e51b815260206004820152603660248201527f5361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f60448201527520746f206e6f6e2d7a65726f20616c6c6f77616e636560501b60648201526084016105de565b6040516001600160a01b0383166024820152604481018290526118d590849063095ea7b360e01b9060640161189e565b603380546001600160a01b0319166001600160a01b0383169081179091556040519081527f869e0abd13cc3a975de7b93be3df1cb2255c802b1cead85963cc79d99f131bee90602001610f84565b611cc86002612710612724565b61ffff168161ffff161115611d0e5760405162461bcd60e51b815260206004820152600c60248201526b08ccaca40e8dede40d0d2ced60a31b60448201526064016105de565b6066805461ffff191661ffff83169081179091556040519081527fc8fcf8ee1425e7e60b8af83735e1eb516d5b9ef05bfd6eece552ebaeb7c75b4890602001610f84565b6001600160a01b038116611da05760405162461bcd60e51b815260206004820152601560248201527424b73b30b634b2103332b29031b7b63632b1ba37b960591b60448201526064016105de565b6066805462010000600160b01b031916620100006001600160a01b038416908102919091179091556040519081527fe5693914d19c789bdee50a362998c0bc8d035a835f9871da5d51152f0582c34f90602001610f84565b6001600160a01b038116611e4e5760405162461bcd60e51b815260206004820152601d60248201527f496e76616c69642063616d706169676e52656d6f74654d616e6167657200000060448201526064016105de565b606780546001600160a01b0319166001600160a01b0383169081179091556040519081527f3647dc83747c62411c2c3b832d3b044db3479bebbaeb800e7eaf100d41d2038e90602001610f84565b806001600160a01b0316611ebc6000805160206127fe8339815191525490565b6001600160a01b03167fc7c0c772add429241571afb3805861fb3cfa2af374534088b76cdb4325a87e9a60405160405180910390a36000805160206127fe83398151915255565b6000611f58826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316611fd59092919063ffffffff16565b8051909150156118d55780806020019051810190611f769190612748565b6118d55760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b60648201526084016105de565b6060611fe48484600085611fee565b90505b9392505050565b60608247101561204f5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b60648201526084016105de565b843b61209d5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016105de565b600080866001600160a01b031685876040516120b9919061278e565b60006040518083038185875af1925050503d80600081146120f6576040519150601f19603f3d011682016040523d82523d6000602084013e6120fb565b606091505b509150915061210b828286612116565b979650505050505050565b60608315612125575081611fe7565b8251156121355782518084602001fd5b8160405162461bcd60e51b81526004016105de91906127aa565b80356001600160a01b038116811461216657600080fd5b919050565b60006020828403121561217d57600080fd5b611fe78261214f565b60008060006060848603121561219b57600080fd5b505081359360208301359350604090920135919050565b600080604083850312156121c557600080fd5b6121ce8361214f565b91506121dc6020840161214f565b90509250929050565b600080604083850312156121f857600080fd5b50508035926020909101359150565b803561ffff8116811461216657600080fd5b60006020828403121561222b57600080fd5b611fe782612207565b60006020828403121561224657600080fd5b5035919050565b803560ff8116811461216657600080fd5b60008060008060008060a0878903121561227757600080fd5b6122808761224d565b955060208701359450604087013567ffffffffffffffff8111156122a357600080fd5b8701601f810189136122b457600080fd5b803567ffffffffffffffff8111156122cb57600080fd5b8960208260051b84010111156122e057600080fd5b969995985060200196606081013595608090910135945092505050565b600080600080600060a0868803121561231557600080fd5b61231e8661214f565b945061232c60208701612207565b935061233a6040870161214f565b92506123486060870161214f565b91506123566080870161214f565b90509295509295909350565b60008060006060848603121561237757600080fd5b6123808461224d565b95602085013595506040909401359392505050565b60008060008060008060c087890312156123ae57600080fd5b6123b78761214f565b95506123c56020880161214f565b94506123d360408801612207565b93506123e16060880161214f565b92506123ef6080880161214f565b91506123fd60a0880161214f565b90509295509295509295565b6020808252600e908201526d1499595b9d1c985b9d0818d85b1b60921b604082015260600190565b60208082526028908201527f43616c6c6572206973206e6f74207468652053747261746567697374206f722060408201526723b7bb32b93737b960c11b606082015260800190565b6020808252601a908201527f43616c6c6572206973206e6f742074686520476f7665726e6f72000000000000604082015260600190565b60208082526014908201527310d85b5c185a59db881b9bdd0818dc99585d195960621b604082015260600190565b845181526020808601516001600160a01b039081169183019190915260408087015160ff1690830152606080870151908301526080958601519582019590955260a081019390935260c083019190915290911660e08201526101000190565b60006020828403121561254f57600080fd5b5051919050565b600081518084526020840193506020830160005b828110156125915781516001600160a01b031686526020958601959091019060010161256a565b5093949350505050565b6080815284516080820152600060208601516125c260a08401826001600160a01b03169052565b5060408601516001600160a01b03811660c08401525060608601516001600160a01b03811660e084015250608086015160ff81166101008401525060a086015161012083015260c086015161014083015260e086015161014061016084015261262f6101c0840182612556565b905061010087015161264d6101808501826001600160a01b03169052565b50610120969096015115156101a083015250602081019390935260408301919091526001600160a01b031660609091015290565b6020808252602e908201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160408201526d191e481a5b9a5d1a585b1a5e995960921b606082015260800190565b80820281158282048414176126f457634e487b7160e01b600052601160045260246000fd5b92915050565b634e487b7160e01b600052601260045260246000fd5b60008261271f5761271f6126fa565b500490565b600061ffff831680612738576127386126fa565b8061ffff84160491505092915050565b60006020828403121561275a57600080fd5b81518015158114611fe757600080fd5b60005b8381101561278557818101518382015260200161276d565b50506000910152565b600082516127a081846020870161276a565b9190910192915050565b60208152600082518060208401526127c981604085016020870161276a565b601f01601f1916919091016040019291505056fe53bf423e48ed90e97d02ab0ebab13b2a235a6bfbe9c321847d5c175333ac45357bea13895fa79d2831e0a9e28edede30099005a50d652d8957cf8a607ee6ca4aa2646970667358221220d1318d1f4703dff5e0c02952434cd50e651a849d1c7ee912022701a46dc4d96b64736f6c634300081c00337bea13895fa79d2831e0a9e28edede30099005a50d652d8957cf8a607ee6ca4a7bea13895fa79d2831e0a9e28edede30099005a50d652d8957cf8a607ee6ca4aa2646970667358221220c379924f842b671bfa8aa0ba25f9fb8cc88302c1e695573a115c2d6f0528983364736f6c634300081c0033
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106100a95760003560e01c8063799a572d11610071578063799a572d1461011657806395b63c1414610129578063a6384c961461013c578063c7af335214610157578063d38bfff41461016f578063f059e3111461018257600080fd5b80630c340a24146100ae578063485cc955146100d3578063570d8e1d146100e85780635d36b190146100fb578063773540b314610103575b600080fd5b6100b66101a9565b6040516001600160a01b0390911681526020015b60405180910390f35b6100e66100e1366004610a71565b6101c6565b005b6033546100b6906001600160a01b031681565b6100e6610292565b6100e6610111366004610aaa565b610338565b6100b6610124366004610ace565b610398565b6100b6610137366004610b0f565b61045c565b6100b673ba5ed099633d3b313e4d5f7bdc1305d3c28ba5ed81565b61015f6107bb565b60405190151581526020016100ca565b6100e661017d366004610aaa565b6107ec565b61019b610190366004610bb6565b60a81c3060601b1790565b6040519081526020016100ca565b60006101c16000805160206136918339815191525490565b905090565b600054610100900460ff16806101df575060005460ff16155b6102475760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084015b60405180910390fd5b600054610100900460ff16158015610269576000805461ffff19166101011790555b610272836108c0565b61027b82610927565b801561028d576000805461ff00191690555b505050565b7f44c4d30b2eaad5130ad70c3ba6972730566f3e6359ab83e800d905c61b1c51db546001600160a01b0316336001600160a01b03161461032d5760405162461bcd60e51b815260206004820152603060248201527f4f6e6c79207468652070656e64696e6720476f7665726e6f722063616e20636f60448201526f6d706c6574652074686520636c61696d60801b606482015260840161023e565b6103363361097b565b565b6103406107bb565b61038c5760405162461bcd60e51b815260206004820152601a60248201527f43616c6c6572206973206e6f742074686520476f7665726e6f72000000000000604482015260640161023e565b61039581610927565b50565b30600090815260208290526040812073ba5ed099633d3b313e4d5f7bdc1305d3c28ba5ed63d323826a826103cc88886109da565b80516020909101206040516001600160e01b031960e085901b1681526004810192909252602482015273ba5ed099633d3b313e4d5f7bdc1305d3c28ba5ed6044820152606401602060405180830381865afa15801561042f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104539190610bcf565b95945050505050565b6033546000906001600160a01b031633148061047b575061047b6107bb565b6104d85760405162461bcd60e51b815260206004820152602860248201527f43616c6c6572206973206e6f74207468652053747261746567697374206f722060448201526723b7bb32b93737b960c11b606482015260840161023e565b60006104e26101a9565b6001600160a01b03160361052b5760405162461bcd60e51b815260206004820152601060248201526f11dbdd995c9b9bdc881b9bdd081cd95d60821b604482015260640161023e565b6033546001600160a01b03166105785760405162461bcd60e51b815260206004820152601260248201527114dd1c985d1959da5cdd081b9bdd081cd95d60721b604482015260640161023e565b606083901c3081146105cc5760405162461bcd60e51b815260206004820152601b60248201527f46726f6e742d72756e2070726f74656374696f6e206661696c65640000000000604482015260640161023e565b600073ba5ed099633d3b313e4d5f7bdc1305d3c28ba5ed6326307668866105f38e8e6109da565b6040518363ffffffff1660e01b8152600401610610929190610c10565b6020604051808303816000875af115801561062f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106539190610bcf565b90506001600160a01b038416158061067c5750836001600160a01b0316816001600160a01b0316145b6106dc5760405162461bcd60e51b815260206004820152602b60248201527f506f6f6c20626f6f73746572206465706c6f79656420617420756e657870656360448201526a746564206164647265737360a81b606482015260840161023e565b806001600160a01b031663f87bc4346106f36101a9565b60335460405160e084901b6001600160e01b03191681526001600160a01b039283166004820152908216602482015261ffff8c1660448201528c821660648201528a8216608482015290891660a482015260c401600060405180830381600087803b15801561076157600080fd5b505af1158015610775573d6000803e3d6000fd5b50506040516001600160a01b03841692507f29517452b3d8f353a0d81b89ef1eb2c73ce0fc391e9d8e46c2c11c068d73bbe59150600090a29a9950505050505050505050565b60006107d36000805160206136918339815191525490565b6001600160a01b0316336001600160a01b031614905090565b6107f46107bb565b6108405760405162461bcd60e51b815260206004820152601a60248201527f43616c6c6572206973206e6f742074686520476f7665726e6f72000000000000604482015260640161023e565b610868817f44c4d30b2eaad5130ad70c3ba6972730566f3e6359ab83e800d905c61b1c51db55565b806001600160a01b03166108886000805160206136918339815191525490565b6001600160a01b03167fa39cc5eb22d0f34d8beaefee8a3f17cc229c1a1d1ef87a5ad47313487b1c4f0d60405160405180910390a350565b806001600160a01b03166108e06000805160206136918339815191525490565b6001600160a01b03167fc7c0c772add429241571afb3805861fb3cfa2af374534088b76cdb4325a87e9a60405160405180910390a360008051602061369183398151915255565b603380546001600160a01b0319166001600160a01b0383169081179091556040519081527f869e0abd13cc3a975de7b93be3df1cb2255c802b1cead85963cc79d99f131bee9060200160405180910390a150565b6001600160a01b0381166109d15760405162461bcd60e51b815260206004820152601a60248201527f4e657720476f7665726e6f722069732061646472657373283029000000000000604482015260640161023e565b610395816108c0565b6060604051806020016109ec90610a4f565b601f1982820381018352601f9091011660408181526001600160a01b03868116602084015285169082015260600160408051601f1981840301815290829052610a389291602001610c4a565b604051602081830303815290604052905092915050565b612a1780610c7a83390190565b6001600160a01b038116811461039557600080fd5b60008060408385031215610a8457600080fd5b8235610a8f81610a5c565b91506020830135610a9f81610a5c565b809150509250929050565b600060208284031215610abc57600080fd5b8135610ac781610a5c565b9392505050565b600080600060608486031215610ae357600080fd5b8335610aee81610a5c565b92506020840135610afe81610a5c565b929592945050506040919091013590565b600080600080600080600080610100898b031215610b2c57600080fd5b8835610b3781610a5c565b97506020890135610b4781610a5c565b96506040890135610b5781610a5c565b9550606089013561ffff81168114610b6e57600080fd5b94506080890135610b7e81610a5c565b935060a0890135610b8e81610a5c565b925060c0890135915060e0890135610ba581610a5c565b809150509295985092959890939650565b600060208284031215610bc857600080fd5b5035919050565b600060208284031215610be157600080fd5b8151610ac781610a5c565b60005b83811015610c07578181015183820152602001610bef565b50506000910152565b8281526040602082015260008251806040840152610c35816060850160208701610bec565b601f01601f1916919091016060019392505050565b60008351610c5c818460208801610bec565b835190830190610c70818360208801610bec565b0194935050505056fe60c060405234801561001057600080fd5b50604051612a17380380612a1783398101604081905261002f916100ea565b6001600160a01b0380831660a0528116608052818161004e6000610067565b50506001600160a01b0391821660a0521660805261011d565b6001600160a01b0381166100876000805160206129f78339815191525490565b6001600160a01b03167fc7c0c772add429241571afb3805861fb3cfa2af374534088b76cdb4325a87e9a60405160405180910390a36000805160206129f783398151915255565b80516001600160a01b03811681146100e557600080fd5b919050565b600080604083850312156100fd57600080fd5b610106836100ce565b9150610114602084016100ce565b90509250929050565b60805160a0516128536101a46000396000818161056a0152818161087b01528181610d7301528181610dae01528181610df3015281816111310152818161116c0152818161120e015281816113270152818161165d0152818161195b01528181611a490152611ad80152600081816103e7015281816111d0015261130201526128536000f3fe6080604052600436106101c65760003560e01c806394095c2d116100f7578063c7af335211610095578063e9a0214311610064578063e9a0214314610522578063ecefc70514610542578063f7c618c114610558578063f87bc4341461058c57600080fd5b8063c7af33521461048f578063d38bfff4146104b4578063d4629800146104d4578063ddca3f43146104f457600080fd5b8063ab34884c116100d1578063ab34884c14610409578063b0c5b7d814610429578063bcfb252c14610449578063c415b95c1461046957600080fd5b806394095c2d14610395578063a42dce80146103b5578063a6f19c84146103d557600080fd5b8063570d8e1d11610164578063773540b31161013e578063773540b31461031f578063833f68c81461033f5780638e0055531461035f5780638ed5b0fc1461037f57600080fd5b8063570d8e1d146102ca5780635d36b190146102ea5780637039e002146102ff57600080fd5b80630c340a24116101a05780630c340a2414610234578063146ffb261461026657806314c89e171461028a5780634707d000146102aa57600080fd5b806304824e70146101d257806305f56809146101f45780630aaef8541461021457600080fd5b366101cd57005b600080fd5b3480156101de57600080fd5b506101f26101ed36600461216b565b6105ac565b005b34801561020057600080fd5b506101f261020f36600461216b565b610755565b34801561022057600080fd5b506101f261022f366004612186565b610785565b34801561024057600080fd5b5061024961095b565b6040516001600160a01b0390911681526020015b60405180910390f35b34801561027257600080fd5b5061027c61a4b181565b60405190815260200161025d565b34801561029657600080fd5b506101f26102a5366004612186565b610978565b3480156102b657600080fd5b506101f26102c53660046121b2565b610aa2565b3480156102d657600080fd5b50603354610249906001600160a01b031681565b3480156102f657600080fd5b506101f2610c1f565b34801561030b57600080fd5b506101f261031a3660046121e5565b610cc5565b34801561032b57600080fd5b506101f261033a36600461216b565b610ec1565b34801561034b57600080fd5b50606754610249906001600160a01b031681565b34801561036b57600080fd5b506101f261037a366004612219565b610eee565b34801561038b57600080fd5b5061027c60695481565b3480156103a157600080fd5b506101f26103b0366004612234565b610f1b565b3480156103c157600080fd5b506101f26103d036600461216b565b610f8f565b3480156103e157600080fd5b506102497f000000000000000000000000000000000000000000000000000000000000000081565b34801561041557600080fd5b506101f261042436600461225e565b610fbc565b34801561043557600080fd5b506101f26104443660046122fd565b61139e565b34801561045557600080fd5b506101f261046436600461216b565b611460565b34801561047557600080fd5b50606654610249906201000090046001600160a01b031681565b34801561049b57600080fd5b506104a461148d565b604051901515815260200161025d565b3480156104c057600080fd5b506101f26104cf36600461216b565b6114be565b3480156104e057600080fd5b50606854610249906001600160a01b031681565b34801561050057600080fd5b5060665461050f9061ffff1681565b60405161ffff909116815260200161025d565b34801561052e57600080fd5b506101f261053d366004612362565b611562565b34801561054e57600080fd5b5061050f61271081565b34801561056457600080fd5b506102497f000000000000000000000000000000000000000000000000000000000000000081565b34801561059857600080fd5b506101f26105a7366004612395565b611731565b6000805160206127de833981519152805460011981016105e75760405162461bcd60e51b81526004016105de90612409565b60405180910390fd5b600282556033546001600160a01b0316331480610607575061060761148d565b6106235760405162461bcd60e51b81526004016105de90612431565b6001600160a01b03831661066c5760405162461bcd60e51b815260206004820152601060248201526f24b73b30b634b2103932b1b2b4bb32b960811b60448201526064016105de565b60405147906000906001600160a01b0386169083908381818185875af1925050503d80600081146106b9576040519150601f19603f3d011682016040523d82523d6000602084013e6106be565b606091505b50509050806107015760405162461bcd60e51b815260206004820152600f60248201526e151c985b9cd9995c8819985a5b1959608a1b60448201526064016105de565b6040805160008152602081018490526001600160a01b0387168183015290517ffb475a842bad10d3800b61bd1a92e716051afba979b124b583bd99a2d1d7bfd59181900360600190a1505060018255505050565b61075d61148d565b6107795760405162461bcd60e51b81526004016105de90612479565b610782816117d9565b50565b6000805160206127de833981519152805460011981016107b75760405162461bcd60e51b81526004016105de90612409565b600282556033546001600160a01b03163314806107d757506107d761148d565b6107f35760405162461bcd60e51b81526004016105de90612431565b6069546000036108155760405162461bcd60e51b81526004016105de906124b0565b6000851161085f5760405162461bcd60e51b8152602060048201526017602482015276496e76616c6964207265776172642070657220766f746560481b60448201526064016105de565b6067546040805160a08101825260695481526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000081166020830152600082840181905260608301526080820189905260685492516335c5ecd560e21b81529381169363d717b3549389936108e693909261a4b1928b9216906004016124de565b6000604051808303818588803b1580156108ff57600080fd5b505af1158015610913573d6000803e3d6000fd5b50505050507f8f283dbedfa7a1926a86469a652c5f13e8f038708d78cbeb0e1950c9e08625028560405161094991815260200190565b60405180910390a15060019055505050565b60006109736000805160206127fe8339815191525490565b905090565b6000805160206127de833981519152805460011981016109aa5760405162461bcd60e51b81526004016105de90612409565b600282556033546001600160a01b03163314806109ca57506109ca61148d565b6109e65760405162461bcd60e51b81526004016105de90612431565b606754604080516020810182526069548152606854915163c533f30560e01b81529051600482015261a4b16024820152604481018690526001600160a01b03918216606482015291169063c533f3059086906084016000604051808303818588803b158015610a5457600080fd5b505af1158015610a68573d6000803e3d6000fd5b5050600060695550506040518681527f5e6eb33a418de5dbbc17f989f7ae362cdfbb1748c5d603137c767027a354edbc9150602001610949565b6000805160206127de83398151915280546001198101610ad45760405162461bcd60e51b81526004016105de90612409565b60028255610ae061148d565b610afc5760405162461bcd60e51b81526004016105de90612479565b6001600160a01b038316610b455760405162461bcd60e51b815260206004820152601060248201526f24b73b30b634b2103932b1b2b4bb32b960811b60448201526064016105de565b6040516370a0823160e01b81523060048201526000906001600160a01b038616906370a0823190602401602060405180830381865afa158015610b8c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bb0919061253d565b9050610bc66001600160a01b0386168583611872565b604080516001600160a01b038088168252602082018490528616918101919091527ffb475a842bad10d3800b61bd1a92e716051afba979b124b583bd99a2d1d7bfd5906060015b60405180910390a15050600190555050565b7f44c4d30b2eaad5130ad70c3ba6972730566f3e6359ab83e800d905c61b1c51db546001600160a01b0316336001600160a01b031614610cba5760405162461bcd60e51b815260206004820152603060248201527f4f6e6c79207468652070656e64696e6720476f7665726e6f722063616e20636f60448201526f6d706c6574652074686520636c61696d60801b60648201526084016105de565b610cc3336118da565b565b6000805160206127de83398151915280546001198101610cf75760405162461bcd60e51b81526004016105de90612409565b600282556033546001600160a01b0316331480610d175750610d1761148d565b610d335760405162461bcd60e51b81526004016105de90612431565b606954600003610d555760405162461bcd60e51b81526004016105de906124b0565b6000610d5f611939565b606754909150610d9d906001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811691166000611b58565b606754610dd7906001600160a01b037f00000000000000000000000000000000000000000000000000000000000000008116911683611b58565b6067546040805160a08101825260695481526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000081166020830152600082840181905260608301869052608083015260685492516335c5ecd560e21b81529381169363d717b354938a93610e5e93909261a4b1928c9216906004016124de565b6000604051808303818588803b158015610e7757600080fd5b505af1158015610e8b573d6000803e3d6000fd5b50505050507fd922add93b22e9295e2ea259b37756ee2ccafa6872cccda342584d40c754c76681604051610c0d91815260200190565b610ec961148d565b610ee55760405162461bcd60e51b81526004016105de90612479565b61078281611c6d565b610ef661148d565b610f125760405162461bcd60e51b81526004016105de90612479565b61078281611cbb565b6033546001600160a01b0316331480610f375750610f3761148d565b610f535760405162461bcd60e51b81526004016105de90612431565b60698190556040518181527f53c4764ec903d5e515c69c93f0b9b2916f9aa3fa54b34caeeae7bb596d7ec0f6906020015b60405180910390a150565b610f9761148d565b610fb35760405162461bcd60e51b81526004016105de90612479565b61078281611d52565b6000805160206127de83398151915280546001198101610fee5760405162461bcd60e51b81526004016105de90612409565b600282556033546001600160a01b031633148061100e575061100e61148d565b61102a5760405162461bcd60e51b81526004016105de90612431565b6069541561107a5760405162461bcd60e51b815260206004820152601860248201527f43616d706169676e20616c72656164792063726561746564000000000000000060448201526064016105de565b60018860ff16116110c95760405162461bcd60e51b8152602060048201526019602482015278496e76616c6964206e756d626572206f6620706572696f647360381b60448201526064016105de565b600087116111135760405162461bcd60e51b8152602060048201526017602482015276496e76616c6964207265776172642070657220766f746560481b60448201526064016105de565b600061111d611939565b60675490915061115b906001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811691166000611b58565b606754611195906001600160a01b037f00000000000000000000000000000000000000000000000000000000000000008116911683611b58565b606760009054906101000a90046001600160a01b03166001600160a01b0316636509497d8660405180610140016040528061a4b181526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602001306001600160a01b031681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031681526020018d60ff1681526020018c81526020018581526020018b8b8080602002602001604051908101604052809392919081815260200183836020028082843760009201829052509385525050506020820181905260409182015260685490516001600160e01b031960e086901b1681526112c5929161a4b1918b916001600160a01b03169060040161259b565b6000604051808303818588803b1580156112de57600080fd5b505af11580156112f2573d6000803e3d6000fd5b5050604080516001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811682527f00000000000000000000000000000000000000000000000000000000000000001660208201529081018c9052606081018590527ffe76983af97e70cb1d5a3f3b21250c6bd2b5b9216dd3829a1cdab060e17ab15b935060800191506113889050565b60405180910390a1505060019055505050505050565b6113a661148d565b6113c25760405162461bcd60e51b81526004016105de90612479565b600054610100900460ff16806113db575060005460ff16155b6113f75760405162461bcd60e51b81526004016105de90612681565b600054610100900460ff16158015611419576000805461ffff19166101011790555b61142286611c6d565b61142b85611cbb565b61143484611d52565b61143d83611df8565b611446826117d9565b8015611458576000805461ff00191690555b505050505050565b61146861148d565b6114845760405162461bcd60e51b81526004016105de90612479565b61078281611df8565b60006114a56000805160206127fe8339815191525490565b6001600160a01b0316336001600160a01b031614905090565b6114c661148d565b6114e25760405162461bcd60e51b81526004016105de90612479565b61150a817f44c4d30b2eaad5130ad70c3ba6972730566f3e6359ab83e800d905c61b1c51db55565b806001600160a01b031661152a6000805160206127fe8339815191525490565b6001600160a01b03167fa39cc5eb22d0f34d8beaefee8a3f17cc229c1a1d1ef87a5ad47313487b1c4f0d60405160405180910390a350565b6000805160206127de833981519152805460011981016115945760405162461bcd60e51b81526004016105de90612409565b600282556033546001600160a01b03163314806115b457506115b461148d565b6115d05760405162461bcd60e51b81526004016105de90612431565b6069546000036115f25760405162461bcd60e51b81526004016105de906124b0565b60008560ff16116116415760405162461bcd60e51b8152602060048201526019602482015278496e76616c6964206e756d626572206f6620706572696f647360381b60448201526064016105de565b6067546040805160a08101825260695481526001600160a01b037f00000000000000000000000000000000000000000000000000000000000000008116602083015260ff891682840152600060608301819052608083015260685492516335c5ecd560e21b81529381169363d717b3549389936116ca93909261a4b1928b9216906004016124de565b6000604051808303818588803b1580156116e357600080fd5b505af11580156116f7573d6000803e3d6000fd5b505060405160ff891681527f71113ae8f52afc8062af1d0ec71513000c9a7b93eeb737ab8fb50f908445d78a935060200191506109499050565b600054610100900460ff168061174a575060005460ff16155b6117665760405162461bcd60e51b81526004016105de90612681565b600054610100900460ff16158015611788576000805461ffff19166101011790555b61179186611c6d565b61179a85611cbb565b6117a384611d52565b6117ac83611df8565b6117b5826117d9565b6117be87611e9c565b80156117d0576000805461ff00191690555b50505050505050565b6001600160a01b0381166118245760405162461bcd60e51b8152602060048201526012602482015271125b9d985b1a59081d9bdd195b585c9ad95d60721b60448201526064016105de565b606880546001600160a01b0319166001600160a01b0383169081179091556040519081527f4d91cd42ff82ea2004fe60a13788b0c4a8ea5cc08105cc9e21098a93547845ec90602001610f84565b6040516001600160a01b0383166024820152604481018290526118d590849063a9059cbb60e01b906064015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152611f03565b505050565b6001600160a01b0381166119305760405162461bcd60e51b815260206004820152601a60248201527f4e657720476f7665726e6f72206973206164647265737328302900000000000060448201526064016105de565b61078281611e9c565b6040516370a0823160e01b815230600482015260009081906001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906370a0823190602401602060405180830381865afa1580156119a2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119c6919061253d565b905060008111611a0e5760405162461bcd60e51b81526020600482015260136024820152724e6f2072657761726420746f206d616e61676560681b60448201526064016105de565b60665460009061271090611a269061ffff16846126cf565b611a309190612710565b90508015611b5257606654611a78906001600160a01b037f00000000000000000000000000000000000000000000000000000000000000008116916201000090041683611872565b60665460408051620100009092046001600160a01b03168252602082018390527f06c5efeff5c320943d265dc4e5f1af95ad523555ce0c1957e367dda5514572df910160405180910390a16040516370a0823160e01b81523060048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa158015611b27573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b4b919061253d565b9250505090565b50919050565b801580611bd25750604051636eb1769f60e11b81523060048201526001600160a01b03838116602483015284169063dd62ed3e90604401602060405180830381865afa158015611bac573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611bd0919061253d565b155b611c3d5760405162461bcd60e51b815260206004820152603660248201527f5361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f60448201527520746f206e6f6e2d7a65726f20616c6c6f77616e636560501b60648201526084016105de565b6040516001600160a01b0383166024820152604481018290526118d590849063095ea7b360e01b9060640161189e565b603380546001600160a01b0319166001600160a01b0383169081179091556040519081527f869e0abd13cc3a975de7b93be3df1cb2255c802b1cead85963cc79d99f131bee90602001610f84565b611cc86002612710612724565b61ffff168161ffff161115611d0e5760405162461bcd60e51b815260206004820152600c60248201526b08ccaca40e8dede40d0d2ced60a31b60448201526064016105de565b6066805461ffff191661ffff83169081179091556040519081527fc8fcf8ee1425e7e60b8af83735e1eb516d5b9ef05bfd6eece552ebaeb7c75b4890602001610f84565b6001600160a01b038116611da05760405162461bcd60e51b815260206004820152601560248201527424b73b30b634b2103332b29031b7b63632b1ba37b960591b60448201526064016105de565b6066805462010000600160b01b031916620100006001600160a01b038416908102919091179091556040519081527fe5693914d19c789bdee50a362998c0bc8d035a835f9871da5d51152f0582c34f90602001610f84565b6001600160a01b038116611e4e5760405162461bcd60e51b815260206004820152601d60248201527f496e76616c69642063616d706169676e52656d6f74654d616e6167657200000060448201526064016105de565b606780546001600160a01b0319166001600160a01b0383169081179091556040519081527f3647dc83747c62411c2c3b832d3b044db3479bebbaeb800e7eaf100d41d2038e90602001610f84565b806001600160a01b0316611ebc6000805160206127fe8339815191525490565b6001600160a01b03167fc7c0c772add429241571afb3805861fb3cfa2af374534088b76cdb4325a87e9a60405160405180910390a36000805160206127fe83398151915255565b6000611f58826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316611fd59092919063ffffffff16565b8051909150156118d55780806020019051810190611f769190612748565b6118d55760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b60648201526084016105de565b6060611fe48484600085611fee565b90505b9392505050565b60608247101561204f5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b60648201526084016105de565b843b61209d5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016105de565b600080866001600160a01b031685876040516120b9919061278e565b60006040518083038185875af1925050503d80600081146120f6576040519150601f19603f3d011682016040523d82523d6000602084013e6120fb565b606091505b509150915061210b828286612116565b979650505050505050565b60608315612125575081611fe7565b8251156121355782518084602001fd5b8160405162461bcd60e51b81526004016105de91906127aa565b80356001600160a01b038116811461216657600080fd5b919050565b60006020828403121561217d57600080fd5b611fe78261214f565b60008060006060848603121561219b57600080fd5b505081359360208301359350604090920135919050565b600080604083850312156121c557600080fd5b6121ce8361214f565b91506121dc6020840161214f565b90509250929050565b600080604083850312156121f857600080fd5b50508035926020909101359150565b803561ffff8116811461216657600080fd5b60006020828403121561222b57600080fd5b611fe782612207565b60006020828403121561224657600080fd5b5035919050565b803560ff8116811461216657600080fd5b60008060008060008060a0878903121561227757600080fd5b6122808761224d565b955060208701359450604087013567ffffffffffffffff8111156122a357600080fd5b8701601f810189136122b457600080fd5b803567ffffffffffffffff8111156122cb57600080fd5b8960208260051b84010111156122e057600080fd5b969995985060200196606081013595608090910135945092505050565b600080600080600060a0868803121561231557600080fd5b61231e8661214f565b945061232c60208701612207565b935061233a6040870161214f565b92506123486060870161214f565b91506123566080870161214f565b90509295509295909350565b60008060006060848603121561237757600080fd5b6123808461224d565b95602085013595506040909401359392505050565b60008060008060008060c087890312156123ae57600080fd5b6123b78761214f565b95506123c56020880161214f565b94506123d360408801612207565b93506123e16060880161214f565b92506123ef6080880161214f565b91506123fd60a0880161214f565b90509295509295509295565b6020808252600e908201526d1499595b9d1c985b9d0818d85b1b60921b604082015260600190565b60208082526028908201527f43616c6c6572206973206e6f74207468652053747261746567697374206f722060408201526723b7bb32b93737b960c11b606082015260800190565b6020808252601a908201527f43616c6c6572206973206e6f742074686520476f7665726e6f72000000000000604082015260600190565b60208082526014908201527310d85b5c185a59db881b9bdd0818dc99585d195960621b604082015260600190565b845181526020808601516001600160a01b039081169183019190915260408087015160ff1690830152606080870151908301526080958601519582019590955260a081019390935260c083019190915290911660e08201526101000190565b60006020828403121561254f57600080fd5b5051919050565b600081518084526020840193506020830160005b828110156125915781516001600160a01b031686526020958601959091019060010161256a565b5093949350505050565b6080815284516080820152600060208601516125c260a08401826001600160a01b03169052565b5060408601516001600160a01b03811660c08401525060608601516001600160a01b03811660e084015250608086015160ff81166101008401525060a086015161012083015260c086015161014083015260e086015161014061016084015261262f6101c0840182612556565b905061010087015161264d6101808501826001600160a01b03169052565b50610120969096015115156101a083015250602081019390935260408301919091526001600160a01b031660609091015290565b6020808252602e908201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160408201526d191e481a5b9a5d1a585b1a5e995960921b606082015260800190565b80820281158282048414176126f457634e487b7160e01b600052601160045260246000fd5b92915050565b634e487b7160e01b600052601260045260246000fd5b60008261271f5761271f6126fa565b500490565b600061ffff831680612738576127386126fa565b8061ffff84160491505092915050565b60006020828403121561275a57600080fd5b81518015158114611fe757600080fd5b60005b8381101561278557818101518382015260200161276d565b50506000910152565b600082516127a081846020870161276a565b9190910192915050565b60208152600082518060208401526127c981604085016020870161276a565b601f01601f1916919091016040019291505056fe53bf423e48ed90e97d02ab0ebab13b2a235a6bfbe9c321847d5c175333ac45357bea13895fa79d2831e0a9e28edede30099005a50d652d8957cf8a607ee6ca4aa2646970667358221220d1318d1f4703dff5e0c02952434cd50e651a849d1c7ee912022701a46dc4d96b64736f6c634300081c00337bea13895fa79d2831e0a9e28edede30099005a50d652d8957cf8a607ee6ca4a7bea13895fa79d2831e0a9e28edede30099005a50d652d8957cf8a607ee6ca4aa2646970667358221220c379924f842b671bfa8aa0ba25f9fb8cc88302c1e695573a115c2d6f0528983364736f6c634300081c0033
Loading...
Loading
Loading...
Loading
Net Worth in USD
$0.00
Net Worth in ETH
0
Multichain Portfolio | 34 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
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.