Source Code
Overview
ETH Balance
0 ETH
Eth Value
$0.00Latest 5 from a total of 5 transactions
| Transaction Hash |
Method
|
Block
|
From
|
|
To
|
||||
|---|---|---|---|---|---|---|---|---|---|
| Set Farming Addr... | 24384389 | 55 days ago | IN | 0 ETH | 0.00003193 | ||||
| Set Fee Discount... | 24384359 | 55 days ago | IN | 0 ETH | 0.0000249 | ||||
| Set Security Reg... | 24384355 | 55 days ago | IN | 0 ETH | 0.00002717 | ||||
| Set Default Fee ... | 24384353 | 55 days ago | IN | 0 ETH | 0.0000179 | ||||
| Set Plugin Deplo... | 24384346 | 55 days ago | IN | 0 ETH | 0.00002848 |
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Loading...
Loading
Cross-Chain Transactions
Loading...
Loading
Contract Name:
BasePluginV3Factory
Compiler Version
v0.8.20+commit.a1b79de6
Optimization Enabled:
Yes with 1000000 runs
Other Settings:
paris EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: BUSL-1.1
pragma solidity =0.8.20;
import './interfaces/IBasePluginV3Factory.sol';
import './interfaces/IPluginV3Deployer.sol';
import './interfaces/plugins/ISecurityPlugin.sol';
import '@cryptoalgebra/integral-core/contracts/interfaces/IAlgebraFactory.sol';
import './libraries/AdaptiveFee.sol';
/// @title Algebra Integral 1.2 default plugin factory
/// @notice This contract creates Algebra adaptive fee plugins for Algebra liquidity pools
/// @dev This plugin factory can only be used for Algebra base pools
contract BasePluginV3Factory is IBasePluginV3Factory {
/// @inheritdoc IBasePluginV3Factory
bytes32 public constant override ALGEBRA_BASE_PLUGIN_FACTORY_ADMINISTRATOR = keccak256('ALGEBRA_BASE_PLUGIN_FACTORY_ADMINISTRATOR');
/// @inheritdoc IBasePluginV3Factory
address public immutable override algebraFactory;
/// @inheritdoc IBasePluginV3Factory
AlgebraFeeConfiguration public override defaultFeeConfiguration; // values of constants for sigmoids in fee calculation formula
/// @inheritdoc IBasePluginV3Factory
address public override farmingAddress;
/// @inheritdoc IBasePluginV3Factory
address public override securityRegistry;
address public reflexRouter;
/// @notice Configuration ID for profit distribution used by plugins created by this factory
bytes32 public reflexConfigId;
/// @inheritdoc IBasePluginV3Factory
address public override feeDiscountRegistry;
/// @inheritdoc IBasePluginV3Factory
mapping(address poolAddress => address pluginAddress) public override pluginByPool;
/// @dev Helper contract address used to deploy plugins (keeps this factory's bytecode smaller)
address public pluginDeployer;
modifier onlyAdministrator() {
require(IAlgebraFactory(algebraFactory).hasRoleOrOwner(ALGEBRA_BASE_PLUGIN_FACTORY_ADMINISTRATOR, msg.sender), 'Only administrator');
_;
}
constructor(address _algebraFactory) {
algebraFactory = _algebraFactory;
defaultFeeConfiguration = AdaptiveFee.initialFeeConfiguration();
emit DefaultFeeConfiguration(defaultFeeConfiguration);
}
/// @inheritdoc IAlgebraPluginFactory
function beforeCreatePoolHook(address pool, address, address, address, address, bytes calldata) external override returns (address) {
require(msg.sender == algebraFactory);
return _createPlugin(pool);
}
/// @inheritdoc IAlgebraPluginFactory
function afterCreatePoolHook(address, address, address) external view override {
require(msg.sender == algebraFactory);
}
function createPluginForExistingCustomPool(address token0, address token1, address customPoolDeployer) external returns (address) {
IAlgebraFactory factory = IAlgebraFactory(algebraFactory);
require(msg.sender == customPoolDeployer || factory.hasRoleOrOwner(factory.POOLS_ADMINISTRATOR_ROLE(), msg.sender), 'Only deployer or admin');
require(token0 != token1);
(token0, token1) = token0 < token1 ? (token0, token1) : (token1, token0);
require(token0 != address(0));
require(customPoolDeployer != address(0), 'Custom pool deployer is required');
address pool = factory.customPoolByPair(customPoolDeployer, token0, token1);
require(pool != address(0), 'Pool not exist');
return _createPlugin(pool);
}
function _createPlugin(address pool) internal returns (address) {
require(pluginByPool[pool] == address(0), 'Already created');
require(pluginDeployer != address(0), 'Plugin deployer not set');
address plugin = IPluginV3Deployer(pluginDeployer).deployPlugin(
pool,
algebraFactory,
address(this),
defaultFeeConfiguration,
reflexRouter,
reflexConfigId,
feeDiscountRegistry
);
ISecurityPlugin(plugin).setSecurityRegistry(securityRegistry);
pluginByPool[pool] = plugin;
return plugin;
}
/// @inheritdoc IBasePluginV3Factory
function setDefaultFeeConfiguration(AlgebraFeeConfiguration calldata newConfig) external override onlyAdministrator {
AdaptiveFee.validateFeeConfiguration(newConfig);
defaultFeeConfiguration = newConfig;
emit DefaultFeeConfiguration(newConfig);
}
/// @inheritdoc IBasePluginV3Factory
function setFarmingAddress(address newFarmingAddress) external override onlyAdministrator {
require(farmingAddress != newFarmingAddress);
farmingAddress = newFarmingAddress;
emit FarmingAddress(newFarmingAddress);
}
/// @inheritdoc IBasePluginV3Factory
function setSecurityRegistry(address _securityRegistry) external override onlyAdministrator {
require(securityRegistry != _securityRegistry);
securityRegistry = _securityRegistry;
emit SecurityRegistry(_securityRegistry);
}
/// @inheritdoc IBasePluginV3Factory
function setFeeDiscountRegistry(address newFeeDiscountRegistry) external override onlyAdministrator {
require(feeDiscountRegistry != newFeeDiscountRegistry);
feeDiscountRegistry = newFeeDiscountRegistry;
emit FeeDiscountRegistry(newFeeDiscountRegistry);
}
/// @dev updates reflex router and config id used by plugins created by this factory
/// @param newReflexRouter The new reflex router address
/// @param newReflexConfigId The new reflex configuration id
function setReflexConfig(address newReflexRouter, bytes32 newReflexConfigId) external onlyAdministrator {
reflexRouter = newReflexRouter;
reflexConfigId = newReflexConfigId;
emit ReflexConfig(newReflexRouter, newReflexConfigId);
}
/// @dev sets the plugin deployer address
/// @param newPluginDeployer The new plugin deployer contract address
function setPluginDeployer(address newPluginDeployer) external onlyAdministrator {
require(newPluginDeployer != address(0), 'Invalid deployer address');
require(pluginDeployer != newPluginDeployer, 'Same deployer address');
pluginDeployer = newPluginDeployer;
emit PluginDeployer(newPluginDeployer);
}
}// SPDX-License-Identifier: GPL-2.0-or-later
pragma solidity >=0.5.0;
pragma abicoder v2;
import './plugin/IAlgebraPluginFactory.sol';
import './vault/IAlgebraVaultFactory.sol';
/// @title The interface for the Algebra Factory
/// @dev Credit to Uniswap Labs under GPL-2.0-or-later license:
/// https://github.com/Uniswap/v3-core/tree/main/contracts/interfaces
interface IAlgebraFactory {
/// @notice Emitted when a process of ownership renounce is started
/// @param timestamp The timestamp of event
/// @param finishTimestamp The timestamp when ownership renounce will be possible to finish
event RenounceOwnershipStart(uint256 timestamp, uint256 finishTimestamp);
/// @notice Emitted when a process of ownership renounce cancelled
/// @param timestamp The timestamp of event
event RenounceOwnershipStop(uint256 timestamp);
/// @notice Emitted when a process of ownership renounce finished
/// @param timestamp The timestamp of ownership renouncement
event RenounceOwnershipFinish(uint256 timestamp);
/// @notice Emitted when a pool is created
/// @param token0 The first token of the pool by address sort order
/// @param token1 The second token of the pool by address sort order
/// @param pool The address of the created pool
event Pool(address indexed token0, address indexed token1, address pool);
/// @notice Emitted when a pool is created
/// @param deployer The corresponding custom deployer contract
/// @param token0 The first token of the pool by address sort order
/// @param token1 The second token of the pool by address sort order
/// @param pool The address of the created pool
event CustomPool(address indexed deployer, address indexed token0, address indexed token1, address pool);
/// @notice Emitted when the default community fee is changed
/// @param newDefaultCommunityFee The new default community fee value
event DefaultCommunityFee(uint16 newDefaultCommunityFee);
/// @notice Emitted when the default tickspacing is changed
/// @param newDefaultTickspacing The new default tickspacing value
event DefaultTickspacing(int24 newDefaultTickspacing);
/// @notice Emitted when the default fee is changed
/// @param newDefaultFee The new default fee value
event DefaultFee(uint16 newDefaultFee);
/// @notice Emitted when the defaultPluginFactory address is changed
/// @param defaultPluginFactoryAddress The new defaultPluginFactory address
event DefaultPluginFactory(address defaultPluginFactoryAddress);
/// @notice Emitted when the vaultFactory address is changed
/// @param newVaultFactory The new vaultFactory address
event VaultFactory(address newVaultFactory);
/// @notice role that can change communityFee and tickspacing in pools
/// @return The hash corresponding to this role
function POOLS_ADMINISTRATOR_ROLE() external view returns (bytes32);
/// @notice role that can call `createCustomPool` function
/// @return The hash corresponding to this role
function CUSTOM_POOL_DEPLOYER() external view returns (bytes32);
/// @notice Returns `true` if `account` has been granted `role` or `account` is owner.
/// @param role The hash corresponding to the role
/// @param account The address for which the role is checked
/// @return bool Whether the address has this role or the owner role or not
function hasRoleOrOwner(bytes32 role, address account) external view returns (bool);
/// @notice Returns the current owner of the factory
/// @dev Can be changed by the current owner via transferOwnership(address newOwner)
/// @return The address of the factory owner
function owner() external view returns (address);
/// @notice Returns the current poolDeployerAddress
/// @return The address of the poolDeployer
function poolDeployer() external view returns (address);
/// @notice Returns the default community fee
/// @return Fee which will be set at the creation of the pool
function defaultCommunityFee() external view returns (uint16);
/// @notice Returns the default fee
/// @return Fee which will be set at the creation of the pool
function defaultFee() external view returns (uint16);
/// @notice Returns the default tickspacing
/// @return Tickspacing which will be set at the creation of the pool
function defaultTickspacing() external view returns (int24);
/// @notice Return the current pluginFactory address
/// @dev This contract is used to automatically set a plugin address in new liquidity pools
/// @return Algebra plugin factory
function defaultPluginFactory() external view returns (IAlgebraPluginFactory);
/// @notice Return the current vaultFactory address
/// @dev This contract is used to automatically set a vault address in new liquidity pools
/// @return Algebra vault factory
function vaultFactory() external view returns (IAlgebraVaultFactory);
/// @notice Returns the default communityFee, tickspacing, fee and communityFeeVault for pool
/// @return communityFee which will be set at the creation of the pool
/// @return tickSpacing which will be set at the creation of the pool
/// @return fee which will be set at the creation of the pool
function defaultConfigurationForPool() external view returns (uint16 communityFee, int24 tickSpacing, uint16 fee);
/// @notice Deterministically computes the pool address given the token0 and token1
/// @dev The method does not check if such a pool has been created
/// @param token0 first token
/// @param token1 second token
/// @return pool The contract address of the Algebra pool
function computePoolAddress(address token0, address token1) external view returns (address pool);
/// @notice Deterministically computes the custom pool address given the customDeployer, token0 and token1
/// @dev The method does not check if such a pool has been created
/// @param customDeployer the address of custom plugin deployer
/// @param token0 first token
/// @param token1 second token
/// @return customPool The contract address of the Algebra pool
function computeCustomPoolAddress(address customDeployer, address token0, address token1) external view returns (address customPool);
/// @notice Returns the pool address for a given pair of tokens, or address 0 if it does not exist
/// @dev tokenA and tokenB may be passed in either token0/token1 or token1/token0 order
/// @param tokenA The contract address of either token0 or token1
/// @param tokenB The contract address of the other token
/// @return pool The pool address
function poolByPair(address tokenA, address tokenB) external view returns (address pool);
/// @notice Returns the custom pool address for a customDeployer and a given pair of tokens, or address 0 if it does not exist
/// @dev tokenA and tokenB may be passed in either token0/token1 or token1/token0 order
/// @param customDeployer The address of custom plugin deployer
/// @param tokenA The contract address of either token0 or token1
/// @param tokenB The contract address of the other token
/// @return customPool The pool address
function customPoolByPair(address customDeployer, address tokenA, address tokenB) external view returns (address customPool);
/// @notice returns keccak256 of AlgebraPool init bytecode.
/// @dev the hash value changes with any change in the pool bytecode
/// @return Keccak256 hash of AlgebraPool contract init bytecode
function POOL_INIT_CODE_HASH() external view returns (bytes32);
/// @return timestamp The timestamp of the beginning of the renounceOwnership process
function renounceOwnershipStartTimestamp() external view returns (uint256 timestamp);
/// @notice Creates a pool for the given two tokens
/// @param tokenA One of the two tokens in the desired pool
/// @param tokenB The other of the two tokens in the desired pool
/// @param data Data for plugin creation
/// @dev tokenA and tokenB may be passed in either order: token0/token1 or token1/token0.
/// The call will revert if the pool already exists or the token arguments are invalid.
/// @return pool The address of the newly created pool
function createPool(address tokenA, address tokenB, bytes calldata data) external returns (address pool);
/// @notice Creates a custom pool for the given two tokens using `deployer` contract
/// @param deployer The address of plugin deployer, also used for custom pool address calculation
/// @param creator The initiator of custom pool creation
/// @param tokenA One of the two tokens in the desired pool
/// @param tokenB The other of the two tokens in the desired pool
/// @param data The additional data bytes
/// @dev tokenA and tokenB may be passed in either order: token0/token1 or token1/token0.
/// The call will revert if the pool already exists or the token arguments are invalid.
/// @return customPool The address of the newly created custom pool
function createCustomPool(
address deployer,
address creator,
address tokenA,
address tokenB,
bytes calldata data
) external returns (address customPool);
/// @dev updates default community fee for new pools
/// @param newDefaultCommunityFee The new community fee, _must_ be <= MAX_COMMUNITY_FEE
function setDefaultCommunityFee(uint16 newDefaultCommunityFee) external;
/// @dev updates default fee for new pools
/// @param newDefaultFee The new fee, _must_ be <= MAX_DEFAULT_FEE
function setDefaultFee(uint16 newDefaultFee) external;
/// @dev updates default tickspacing for new pools
/// @param newDefaultTickspacing The new tickspacing, _must_ be <= MAX_TICK_SPACING and >= MIN_TICK_SPACING
function setDefaultTickspacing(int24 newDefaultTickspacing) external;
/// @dev updates pluginFactory address
/// @param newDefaultPluginFactory address of new plugin factory
function setDefaultPluginFactory(address newDefaultPluginFactory) external;
/// @dev updates vaultFactory address
/// @param newVaultFactory address of new vault factory
function setVaultFactory(address newVaultFactory) external;
/// @notice Starts process of renounceOwnership. After that, a certain period
/// of time must pass before the ownership renounce can be completed.
function startRenounceOwnership() external;
/// @notice Stops process of renounceOwnership and removes timer.
function stopRenounceOwnership() external;
}// SPDX-License-Identifier: GPL-2.0-or-later
pragma solidity >=0.5.0;
/// @title An interface for a contract that is capable of deploying Algebra plugins
/// @dev Such a factory can be used for automatic plugin creation for new pools.
/// Also a factory be used as an entry point for custom (additional) pools creation
interface IAlgebraPluginFactory {
/// @notice Deploys new plugin contract for pool
/// @param pool The address of the new pool
/// @param creator The address that initiated the pool creation
/// @param deployer The address of new plugin deployer contract (0 if not used)
/// @param token0 First token of the pool
/// @param token1 Second token of the pool
/// @return New plugin address
function beforeCreatePoolHook(
address pool,
address creator,
address deployer,
address token0,
address token1,
bytes calldata data
) external returns (address);
/// @notice Called after the pool is created
/// @param plugin The plugin address
/// @param pool The address of the new pool
/// @param deployer The address of new plugin deployer contract (0 if not used)
function afterCreatePoolHook(address plugin, address pool, address deployer) external;
}// SPDX-License-Identifier: GPL-2.0-or-later
pragma solidity >=0.5.0;
/// @title The interface for the Algebra Vault Factory
/// @notice This contract can be used for automatic vaults creation
/// @dev Version: Algebra Integral
interface IAlgebraVaultFactory {
/// @notice returns address of the community fee vault for the pool
/// @param pool the address of Algebra Integral pool
/// @return communityFeeVault the address of community fee vault
function getVaultForPool(address pool) external view returns (address communityFeeVault);
/// @notice creates the community fee vault for the pool if needed
/// @param pool the address of Algebra Integral pool
/// @return communityFeeVault the address of community fee vault
function createVaultForPool(
address pool,
address creator,
address deployer,
address token0,
address token1
) external returns (address communityFeeVault);
}// SPDX-License-Identifier: GPL-2.0-or-later
pragma solidity >=0.5.0 <0.9.0;
/// @title Contains common constants for Algebra contracts
/// @dev Constants moved to the library, not the base contract, to further emphasize their constant nature
library Constants {
uint8 internal constant RESOLUTION = 96;
uint256 internal constant Q96 = 1 << 96;
uint256 internal constant Q128 = 1 << 128;
uint24 internal constant FEE_DENOMINATOR = 1e6;
uint16 internal constant FLASH_FEE = 0.01e4; // fee for flash loan in hundredths of a bip (0.01%)
uint16 internal constant INIT_DEFAULT_FEE = 0.05e4; // init default fee value in hundredths of a bip (0.05%)
uint16 internal constant MAX_DEFAULT_FEE = 5e4; // max default fee value in hundredths of a bip (5%)
int24 internal constant INIT_DEFAULT_TICK_SPACING = 60;
int24 internal constant MAX_TICK_SPACING = 500;
int24 internal constant MIN_TICK_SPACING = 1;
// the frequency with which the accumulated community fees are sent to the vault
uint32 internal constant FEE_TRANSFER_FREQUENCY = 8 hours;
// max(uint128) / (MAX_TICK - MIN_TICK)
uint128 internal constant MAX_LIQUIDITY_PER_TICK = 191757638537527648490752896198553;
uint16 internal constant MAX_COMMUNITY_FEE = 1e3; // 100%
uint256 internal constant COMMUNITY_FEE_DENOMINATOR = 1e3;
// role that can change settings in pools
bytes32 internal constant POOLS_ADMINISTRATOR_ROLE = keccak256('POOLS_ADMINISTRATOR');
}// SPDX-License-Identifier: GPL-2.0-or-later
pragma solidity >=0.5.0;
/// @notice coefficients for sigmoids: α / (1 + e^( (β-x) / γ))
/// @dev alpha1 + alpha2 + baseFee must be <= type(uint16).max
struct AlgebraFeeConfiguration {
uint16 alpha1; // max value of the first sigmoid
uint16 alpha2; // max value of the second sigmoid
uint32 beta1; // shift along the x-axis for the first sigmoid
uint32 beta2; // shift along the x-axis for the second sigmoid
uint16 gamma1; // horizontal stretch factor for the first sigmoid
uint16 gamma2; // horizontal stretch factor for the second sigmoid
uint16 baseFee; // minimum possible fee
}// SPDX-License-Identifier: GPL-2.0-or-later
pragma solidity >=0.5.0;
pragma abicoder v2;
import '@cryptoalgebra/integral-core/contracts/interfaces/plugin/IAlgebraPluginFactory.sol';
import '../base/AlgebraFeeConfiguration.sol';
/// @title The interface for the BasePluginV1Factory
/// @notice This contract creates Algebra default plugins for Algebra liquidity pools
interface IBasePluginV3Factory is IAlgebraPluginFactory {
/// @notice Emitted when the default fee configuration is changed
/// @param newConfig The structure with dynamic fee parameters
/// @dev See the AdaptiveFee library for more details
event DefaultFeeConfiguration(AlgebraFeeConfiguration newConfig);
/// @notice Emitted when the security registry address is changed
/// @param securityRegistry The security registry address after the address was changed
event SecurityRegistry(address securityRegistry);
/// @notice Emitted when the farming address is changed
/// @param newFarmingAddress The farming address after the address was changed
event FarmingAddress(address newFarmingAddress);
/// @notice Emitted when the reflex router or config id is changed
/// @param reflexRouter The reflex router address after the change
/// @param reflexConfigId The reflex configuration id after the change
event ReflexConfig(address reflexRouter, bytes32 reflexConfigId);
/// @notice Emitted when the fee discount registry address is changed
/// @param registry The fee discount registry address after the address was changed
event FeeDiscountRegistry(address registry);
/// @notice Emitted when the plugin deployer address is changed
/// @param deployer The plugin deployer contract address after the address was changed
event PluginDeployer(address deployer);
/// @notice The hash of 'ALGEBRA_BASE_PLUGIN_FACTORY_ADMINISTRATOR' used as role
/// @dev allows to change settings of BasePluginV1Factory
function ALGEBRA_BASE_PLUGIN_FACTORY_ADMINISTRATOR() external pure returns (bytes32);
/// @notice Returns the address of AlgebraFactory
/// @return The AlgebraFactory contract address
function algebraFactory() external view returns (address);
/// @notice Current default dynamic fee configuration
/// @dev See the AdaptiveFee struct for more details about params.
/// This value is set by default in new plugins
function defaultFeeConfiguration()
external
view
returns (uint16 alpha1, uint16 alpha2, uint32 beta1, uint32 beta2, uint16 gamma1, uint16 gamma2, uint16 baseFee);
/// @notice Returns current farming address
/// @return The farming contract address
function farmingAddress() external view returns (address);
/// @notice Returns current securityRegistry address
/// @return The securityRegistry contract address
function securityRegistry() external view returns (address);
/// @notice Returns current fee discount registry address
/// @return The fee discount registry contract address
function feeDiscountRegistry() external view returns (address);
/// @notice Returns address of plugin created for given AlgebraPool
/// @param pool The address of AlgebraPool
/// @return The address of corresponding plugin
function pluginByPool(address pool) external view returns (address);
/// @notice Create plugin for already existing pool
/// @param token0 The address of first token in pool
/// @param token1 The address of second token in pool
/// @return The address of created plugin
function createPluginForExistingCustomPool(address token0, address token1, address customPoolDeployer) external returns (address);
/// @notice Changes initial fee configuration for new pools
/// @dev changes coefficients for sigmoids: α / (1 + e^( (β-x) / γ))
/// alpha1 + alpha2 + baseFee (max possible fee) must be <= type(uint16).max and gammas must be > 0
/// @param newConfig new default fee configuration. See the #AdaptiveFee.sol library for details
function setDefaultFeeConfiguration(AlgebraFeeConfiguration calldata newConfig) external;
/// @dev updates farmings manager address on the factory
/// @param newFarmingAddress The new tokenomics contract address
function setFarmingAddress(address newFarmingAddress) external;
/// @dev updates securoty registry address on the factory
/// @param newSecurityRegistry The new security registry contract address
function setSecurityRegistry(address newSecurityRegistry) external;
/// @dev updates fee discount registry address on the factory
/// @param newFeeDiscountRegistry The new fee discount registry contract address
function setFeeDiscountRegistry(address newFeeDiscountRegistry) external;
}// SPDX-License-Identifier: BUSL-1.1
pragma solidity =0.8.20;
import '../base/AlgebraFeeConfiguration.sol';
/// @title Interface for PluginV3Deployer
/// @notice Used by BasePluginV3Factory to deploy plugins without importing the deployer contract
interface IPluginV3Deployer {
function deployPlugin(
address pool,
address algebraFactory,
address pluginFactory,
AlgebraFeeConfiguration memory defaultFeeConfiguration,
address reflexRouter,
bytes32 reflexConfigId,
address feeDiscountRegistry
) external returns (address plugin);
}// SPDX-License-Identifier: GPL-2.0-or-later
pragma solidity >=0.5.0;
interface ISecurityPlugin {
function setSecurityRegistry(address registry) external;
function getSecurityRegistry() external view returns (address);
event SecurityRegistry(address registry);
error PoolDisabled();
error BurnOnly();
}// SPDX-License-Identifier: BUSL-1.1
pragma solidity =0.8.20;
import '@cryptoalgebra/integral-core/contracts/libraries/Constants.sol';
import '../base/AlgebraFeeConfiguration.sol';
import '../types/AlgebraFeeConfigurationU144.sol';
/// @title AdaptiveFee
/// @notice Calculates fee based on combination of sigmoids
/// @dev Version for AlgebraBasePluginV1
library AdaptiveFee {
uint16 internal constant INITIAL_MIN_FEE = 0.01e4; // 0.01%
/// @notice Returns default initial fee configuration
function initialFeeConfiguration() internal pure returns (AlgebraFeeConfiguration memory) {
return
AlgebraFeeConfiguration({
alpha1: 3000 - INITIAL_MIN_FEE, // max value of the first sigmoid in hundredths of a bip, i.e. 1e-6
alpha2: 15000 - 3000, // max value of the second sigmoid in hundredths of a bip, i.e. 1e-6
beta1: 360, // shift along the x-axis (volatility) for the first sigmoid
beta2: 60000, // shift along the x-axis (volatility) for the second sigmoid
gamma1: 59, // horizontal stretch factor for the first sigmoid
gamma2: 8500, // horizontal stretch factor for the second sigmoid
baseFee: INITIAL_MIN_FEE // in hundredths of a bip, i.e. 1e-6
});
}
/// @notice Validates fee configuration.
/// @dev Maximum fee value capped by baseFee + alpha1 + alpha2 must be <= type(uint16).max
/// gammas must be > 0
function validateFeeConfiguration(AlgebraFeeConfiguration memory _config) internal pure {
require(uint256(_config.alpha1) + uint256(_config.alpha2) + uint256(_config.baseFee) <= type(uint16).max, 'Max fee exceeded');
require(_config.gamma1 != 0 && _config.gamma2 != 0, 'Gammas must be > 0');
}
/// @notice Calculates fee based on formula:
/// baseFee + sigmoid1(volatility) + sigmoid2(volatility)
/// maximum value capped by baseFee + alpha1 + alpha2
function getFee(uint88 volatility, AlgebraFeeConfigurationU144 config) internal pure returns (uint16 fee) {
unchecked {
volatility /= 15; // normalize for 15 sec interval
uint256 sumOfSigmoids = sigmoid(volatility, config.gamma1(), config.alpha1(), config.beta1()) +
sigmoid(volatility, config.gamma2(), config.alpha2(), config.beta2());
uint256 result = uint256(config.baseFee()) + sumOfSigmoids;
assert(result <= type(uint16).max); // should always be true
return uint16(result); // safe since alpha1 + alpha2 + baseFee _must_ be <= type(uint16).max
}
}
/// @notice calculates α / (1 + e^( (β-x) / γ))
/// that is a sigmoid with a maximum value of α, x-shifted by β, and stretched by γ
/// @dev returns uint256 for fuzzy testing. Guaranteed that the result is not greater than alpha
function sigmoid(uint256 x, uint16 g, uint16 alpha, uint256 beta) internal pure returns (uint256 res) {
unchecked {
if (x > beta) {
x = x - beta;
if (x >= 6 * uint256(g)) return alpha; // so x < 19 bits
uint256 g4 = uint256(g) ** 4; // < 64 bits (4*16)
uint256 ex = expXg4(x, g, g4); // < 155 bits
res = (alpha * ex) / (g4 + ex); // in worst case: (16 + 155 bits) / 155 bits
// so res <= alpha
} else {
x = beta - x;
if (x >= 6 * uint256(g)) return 0; // so x < 19 bits
uint256 g4 = uint256(g) ** 4; // < 64 bits (4*16)
uint256 ex = g4 + expXg4(x, g, g4); // < 156 bits
res = (alpha * g4) / ex; // in worst case: (16 + 128 bits) / 156 bits
// g8 <= ex, so res <= alpha
}
}
}
/// @notice calculates e^(x/g) * g^4 in a series, since (around zero):
/// e^x = 1 + x + x^2/2 + ... + x^n/n! + ...
/// e^(x/g) = 1 + x/g + x^2/(2*g^2) + ... + x^(n)/(g^n * n!) + ...
/// @dev has good accuracy only if x/g < 6
function expXg4(uint256 x, uint16 g, uint256 gHighestDegree) internal pure returns (uint256 res) {
uint256 closestValue; // nearest 'table' value of e^(x/g), multiplied by 10^20
assembly {
let xdg := div(x, g)
switch xdg
case 0 {
closestValue := 100000000000000000000 // 1
}
case 1 {
closestValue := 271828182845904523536 // ~= e
}
case 2 {
closestValue := 738905609893065022723 // ~= e^2
}
case 3 {
closestValue := 2008553692318766774092 // ~= e^3
}
case 4 {
closestValue := 5459815003314423907811 // ~= e^4
}
default {
closestValue := 14841315910257660342111 // ~= e^5
}
x := mod(x, g)
}
unchecked {
if (x >= g / 2) {
// (x - closestValue) >= 0.5, so closestValue := closestValue * e^0.5
x -= g / 2;
closestValue = (closestValue * 164872127070012814684) / 1e20;
}
// After calculating the closestValue x/g is <= 0.5, so that the series in the neighborhood of zero converges with sufficient speed
uint256 xLowestDegree = x;
res = gHighestDegree; // g**4, res < 64 bits
gHighestDegree /= g; // g**3
res += xLowestDegree * gHighestDegree; // g**4 + x*g**3, res < 68
gHighestDegree /= g; // g**2
xLowestDegree *= x; // x**2
// g**4 + x * g**3 + (x**2 * g**2) / 2, res < 71
res += (xLowestDegree * gHighestDegree) / 2;
gHighestDegree /= g; // g
xLowestDegree *= x; // x**3
// g^4 + x * g^3 + (x^2 * g^2)/2 + x^3(g*4 + x)/24, res < 73
res += (xLowestDegree * g * 4 + xLowestDegree * x) / 24;
// res = g^4 * (1 + x/g + x^2/(2*g^2) + x^3/(6*g^3) + x^4/(24*g^4)) * closestValue / 10^20, closestValue < 75 bits, res < 155
res = (res * closestValue) / (1e20);
}
}
}// SPDX-License-Identifier: BUSL-1.1
pragma solidity =0.8.20;
import '../base/AlgebraFeeConfiguration.sol';
type AlgebraFeeConfigurationU144 is uint144;
using AlgebraFeeConfigurationU144Lib for AlgebraFeeConfigurationU144 global;
/// @title AdaptiveFee packed configuration library
/// @notice Used to interact with uint144-packed fee config
/// @dev Structs are not packed in storage with neighboring values, but uint144 can be packed
library AlgebraFeeConfigurationU144Lib {
uint256 private constant UINT16_MASK = 0xFFFF;
uint256 private constant UINT32_MASK = 0xFFFFFFFF;
// alpha1 offset is 0
uint256 private constant ALPHA2_OFFSET = 16;
uint256 private constant BETA1_OFFSET = 32;
uint256 private constant BETA2_OFFSET = 64;
uint256 private constant GAMMA1_OFFSET = 96;
uint256 private constant GAMMA2_OFFSET = 112;
uint256 private constant BASE_FEE_OFFSET = 128;
function pack(AlgebraFeeConfiguration memory config) internal pure returns (AlgebraFeeConfigurationU144) {
uint144 _config = uint144(
(uint256(config.baseFee) << BASE_FEE_OFFSET) |
(uint256(config.gamma2) << GAMMA2_OFFSET) |
(uint256(config.gamma1) << GAMMA1_OFFSET) |
(uint256(config.beta2) << BETA2_OFFSET) |
(uint256(config.beta1) << BETA1_OFFSET) |
(uint256(config.alpha2) << ALPHA2_OFFSET) |
uint256(config.alpha1)
);
return AlgebraFeeConfigurationU144.wrap(_config);
}
function alpha1(AlgebraFeeConfigurationU144 config) internal pure returns (uint16 _alpha1) {
assembly {
_alpha1 := and(UINT16_MASK, config)
}
}
function alpha2(AlgebraFeeConfigurationU144 config) internal pure returns (uint16 _alpha2) {
assembly {
_alpha2 := and(UINT16_MASK, shr(ALPHA2_OFFSET, config))
}
}
function beta1(AlgebraFeeConfigurationU144 config) internal pure returns (uint32 _beta1) {
assembly {
_beta1 := and(UINT32_MASK, shr(BETA1_OFFSET, config))
}
}
function beta2(AlgebraFeeConfigurationU144 config) internal pure returns (uint32 _beta2) {
assembly {
_beta2 := and(UINT32_MASK, shr(BETA2_OFFSET, config))
}
}
function gamma1(AlgebraFeeConfigurationU144 config) internal pure returns (uint16 _gamma1) {
assembly {
_gamma1 := and(UINT16_MASK, shr(GAMMA1_OFFSET, config))
}
}
function gamma2(AlgebraFeeConfigurationU144 config) internal pure returns (uint16 _gamma2) {
assembly {
_gamma2 := and(UINT16_MASK, shr(GAMMA2_OFFSET, config))
}
}
function baseFee(AlgebraFeeConfigurationU144 config) internal pure returns (uint16 _baseFee) {
assembly {
_baseFee := and(UINT16_MASK, shr(BASE_FEE_OFFSET, config))
}
}
}{
"evmVersion": "paris",
"optimizer": {
"enabled": true,
"runs": 1000000
},
"metadata": {
"bytecodeHash": "none"
},
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"address","name":"_algebraFactory","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"components":[{"internalType":"uint16","name":"alpha1","type":"uint16"},{"internalType":"uint16","name":"alpha2","type":"uint16"},{"internalType":"uint32","name":"beta1","type":"uint32"},{"internalType":"uint32","name":"beta2","type":"uint32"},{"internalType":"uint16","name":"gamma1","type":"uint16"},{"internalType":"uint16","name":"gamma2","type":"uint16"},{"internalType":"uint16","name":"baseFee","type":"uint16"}],"indexed":false,"internalType":"struct AlgebraFeeConfiguration","name":"newConfig","type":"tuple"}],"name":"DefaultFeeConfiguration","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"newFarmingAddress","type":"address"}],"name":"FarmingAddress","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"registry","type":"address"}],"name":"FeeDiscountRegistry","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"deployer","type":"address"}],"name":"PluginDeployer","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"reflexRouter","type":"address"},{"indexed":false,"internalType":"bytes32","name":"reflexConfigId","type":"bytes32"}],"name":"ReflexConfig","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"securityRegistry","type":"address"}],"name":"SecurityRegistry","type":"event"},{"inputs":[],"name":"ALGEBRA_BASE_PLUGIN_FACTORY_ADMINISTRATOR","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"afterCreatePoolHook","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[],"name":"algebraFactory","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"pool","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"beforeCreatePoolHook","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token0","type":"address"},{"internalType":"address","name":"token1","type":"address"},{"internalType":"address","name":"customPoolDeployer","type":"address"}],"name":"createPluginForExistingCustomPool","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"defaultFeeConfiguration","outputs":[{"internalType":"uint16","name":"alpha1","type":"uint16"},{"internalType":"uint16","name":"alpha2","type":"uint16"},{"internalType":"uint32","name":"beta1","type":"uint32"},{"internalType":"uint32","name":"beta2","type":"uint32"},{"internalType":"uint16","name":"gamma1","type":"uint16"},{"internalType":"uint16","name":"gamma2","type":"uint16"},{"internalType":"uint16","name":"baseFee","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"farmingAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"feeDiscountRegistry","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"poolAddress","type":"address"}],"name":"pluginByPool","outputs":[{"internalType":"address","name":"pluginAddress","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pluginDeployer","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"reflexConfigId","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"reflexRouter","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"securityRegistry","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"uint16","name":"alpha1","type":"uint16"},{"internalType":"uint16","name":"alpha2","type":"uint16"},{"internalType":"uint32","name":"beta1","type":"uint32"},{"internalType":"uint32","name":"beta2","type":"uint32"},{"internalType":"uint16","name":"gamma1","type":"uint16"},{"internalType":"uint16","name":"gamma2","type":"uint16"},{"internalType":"uint16","name":"baseFee","type":"uint16"}],"internalType":"struct AlgebraFeeConfiguration","name":"newConfig","type":"tuple"}],"name":"setDefaultFeeConfiguration","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newFarmingAddress","type":"address"}],"name":"setFarmingAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newFeeDiscountRegistry","type":"address"}],"name":"setFeeDiscountRegistry","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newPluginDeployer","type":"address"}],"name":"setPluginDeployer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newReflexRouter","type":"address"},{"internalType":"bytes32","name":"newReflexConfigId","type":"bytes32"}],"name":"setReflexConfig","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_securityRegistry","type":"address"}],"name":"setSecurityRegistry","outputs":[],"stateMutability":"nonpayable","type":"function"}]Contract Creation Code
60a06040523480156200001157600080fd5b506040516200225a3803806200225a833981016040819052620000349162000249565b6001600160a01b0381166080526200004b620001bf565b80516000805460208401516040808601516060870151608088015160a089015160c09099015161ffff908116600160801b0261ffff60801b199a8216600160701b0261ffff60701b199383166c01000000000000000000000000029390931663ffffffff60601b1963ffffffff958616680100000000000000000263ffffffff60401b19969097166401000000000295909516600160201b600160601b0319988416620100000263ffffffff19909a1693909b16929092179790971795909516979097179190911716919091179390931793909316929092178255517fe04232512a5cb82c08e0f9b1f51432930cd7a0b7ea9f9f916f080cb0b4ac644b91620001b091600060e082019050825461ffff8082168452808260101c16602085015263ffffffff808360201c166040860152808360401c16606086015250808260601c166080850152808260701c1660a0850152808260801c1660c0850152505092915050565b60405180910390a150620002ac565b6040805160e08082018352600080835260208301819052828401819052606083018190526080830181905260a0830181905260c0830152825190810190925290806200020f6064610bb86200027b565b61ffff168152612ee06020820152610168604082015261ea606060820152603b608082015261213460a0820152606460c090910152919050565b6000602082840312156200025c57600080fd5b81516001600160a01b03811681146200027457600080fd5b9392505050565b61ffff828116828216039080821115620002a557634e487b7160e01b600052601160045260246000fd5b5092915050565b608051611f4c6200030e600039600081816102fd0152818161042c01528181610845015281816108d801528181610a9701528181610c3601528181610cb901528181610e8d015281816110610152818161130f01526115b80152611f4c6000f3fe608060405234801561001057600080fd5b50600436106101515760003560e01c8063a7b64b04116100cd578063cdef16f611610081578063e1d03ecf11610066578063e1d03ecf146103d5578063f20cdc1a146103f5578063f718949a1461041557600080fd5b8063cdef16f61461038c578063d2cfc1f0146103c257600080fd5b8063b271039e116100b2578063b271039e14610332578063c3da797814610352578063cddff2691461036557600080fd5b8063a7b64b04146102f8578063b001f6181461031f57600080fd5b806364fae8a9116101245780638d5ef8d1116101095780638d5ef8d1146102ae578063915d61c2146102c15780639b21f9ae146102d857600080fd5b806364fae8a91461027b5780638a2ade581461028e57600080fd5b80630624e2be146101565780631d0338d9146101935780632e04369a146101a65780634e09a96a146101bb575b600080fd5b610169610164366004611847565b610428565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b6101696101a1366004611892565b61082b565b6101b96101b4366004611962565b610884565b005b6000546102339061ffff8082169162010000810482169163ffffffff6401000000008304811692680100000000000000008104909116916c0100000000000000000000000082048116916e01000000000000000000000000000081048216917001000000000000000000000000000000009091041687565b6040805161ffff9889168152968816602088015263ffffffff9586169087015293909216606085015284166080840152831660a08301529190911660c082015260e00161018a565b6101b961028936600461198e565b610a43565b6001546101699073ffffffffffffffffffffffffffffffffffffffff1681565b6101b96102bc366004611847565b610c1e565b6102ca60045481565b60405190815260200161018a565b6002546101699073ffffffffffffffffffffffffffffffffffffffff1681565b6101697f000000000000000000000000000000000000000000000000000000000000000081565b6101b961032d36600461198e565b610c65565b6007546101699073ffffffffffffffffffffffffffffffffffffffff1681565b6101b961036036600461198e565b610e39565b6102ca7f267da724c255813ae00f4522fe843cb70148a4b8099cbc5af64f9a4151e55ed681565b61016961039a36600461198e565b60066020526000908152604090205473ffffffffffffffffffffffffffffffffffffffff1681565b6101b96103d036600461198e565b61100d565b6003546101699073ffffffffffffffffffffffffffffffffffffffff1681565b6005546101699073ffffffffffffffffffffffffffffffffffffffff1681565b6101b96104233660046119b2565b6112bb565b60007f00000000000000000000000000000000000000000000000000000000000000003373ffffffffffffffffffffffffffffffffffffffff8416148061057357508073ffffffffffffffffffffffffffffffffffffffff1663e8ae2b698273ffffffffffffffffffffffffffffffffffffffff1663b500a48b6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156104d1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104f591906119ca565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b1681526004810191909152336024820152604401602060405180830381865afa15801561054f573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061057391906119e3565b6105de576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c79206465706c6f796572206f722061646d696e0000000000000000000060448201526064015b60405180910390fd5b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff160361061657600080fd5b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1610610650578385610653565b84845b909550935073ffffffffffffffffffffffffffffffffffffffff851661067857600080fd5b73ffffffffffffffffffffffffffffffffffffffff83166106f5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f437573746f6d20706f6f6c206465706c6f79657220697320726571756972656460448201526064016105d5565b6040517f23da36cc00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff848116600483015286811660248301528581166044830152600091908316906323da36cc90606401602060405180830381865afa158015610775573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107999190611a05565b905073ffffffffffffffffffffffffffffffffffffffff8116610818576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f506f6f6c206e6f7420657869737400000000000000000000000000000000000060448201526064016105d5565b6108218161144b565b9695505050505050565b60003373ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000161461086f57600080fd5b6108788861144b565b98975050505050505050565b6040517fe8ae2b690000000000000000000000000000000000000000000000000000000081527f267da724c255813ae00f4522fe843cb70148a4b8099cbc5af64f9a4151e55ed660048201523360248201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff169063e8ae2b6990604401602060405180830381865afa158015610934573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061095891906119e3565b6109be576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f4f6e6c792061646d696e6973747261746f72000000000000000000000000000060448201526064016105d5565b600380547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8416908117909155600482905560408051918252602082018390527f2a6990173d4d27e6fc9962c340d27067d1a6bb7aeefbc291b62a21d7faf0d920910160405180910390a15050565b6040517fe8ae2b690000000000000000000000000000000000000000000000000000000081527f267da724c255813ae00f4522fe843cb70148a4b8099cbc5af64f9a4151e55ed660048201523360248201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff169063e8ae2b6990604401602060405180830381865afa158015610af3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b1791906119e3565b610b7d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f4f6e6c792061646d696e6973747261746f72000000000000000000000000000060448201526064016105d5565b60025473ffffffffffffffffffffffffffffffffffffffff808316911603610ba457600080fd5b600280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040519081527f9c2a61186234594f572ba9fd3d6137c9e751c20d5cad21e5c4bf008a768b3657906020015b60405180910390a150565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610c6057600080fd5b505050565b6040517fe8ae2b690000000000000000000000000000000000000000000000000000000081527f267da724c255813ae00f4522fe843cb70148a4b8099cbc5af64f9a4151e55ed660048201523360248201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff169063e8ae2b6990604401602060405180830381865afa158015610d15573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d3991906119e3565b610d9f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f4f6e6c792061646d696e6973747261746f72000000000000000000000000000060448201526064016105d5565b60015473ffffffffffffffffffffffffffffffffffffffff808316911603610dc657600080fd5b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040519081527f56b9e8342f530796ceed0d5529abdcdeae6e4f2ac1dc456ceb73bbda898e0cd390602001610c13565b6040517fe8ae2b690000000000000000000000000000000000000000000000000000000081527f267da724c255813ae00f4522fe843cb70148a4b8099cbc5af64f9a4151e55ed660048201523360248201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff169063e8ae2b6990604401602060405180830381865afa158015610ee9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f0d91906119e3565b610f73576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f4f6e6c792061646d696e6973747261746f72000000000000000000000000000060448201526064016105d5565b60055473ffffffffffffffffffffffffffffffffffffffff808316911603610f9a57600080fd5b600580547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040519081527f3b1f0d57f07483280d598ef402c5b2b96be1a42e65b21992bdafea3476b6532790602001610c13565b6040517fe8ae2b690000000000000000000000000000000000000000000000000000000081527f267da724c255813ae00f4522fe843cb70148a4b8099cbc5af64f9a4151e55ed660048201523360248201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff169063e8ae2b6990604401602060405180830381865afa1580156110bd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110e191906119e3565b611147576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f4f6e6c792061646d696e6973747261746f72000000000000000000000000000060448201526064016105d5565b73ffffffffffffffffffffffffffffffffffffffff81166111c4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f496e76616c6964206465706c6f7965722061646472657373000000000000000060448201526064016105d5565b60075473ffffffffffffffffffffffffffffffffffffffff808316911603611248576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f53616d65206465706c6f7965722061646472657373000000000000000000000060448201526064016105d5565b600780547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040519081527ffc38c91ab5781475eacf5b1c697bb748459ee6ee1a09876b34d955db0808983690602001610c13565b6040517fe8ae2b690000000000000000000000000000000000000000000000000000000081527f267da724c255813ae00f4522fe843cb70148a4b8099cbc5af64f9a4151e55ed660048201523360248201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff169063e8ae2b6990604401602060405180830381865afa15801561136b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061138f91906119e3565b6113f5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f4f6e6c792061646d696e6973747261746f72000000000000000000000000000060448201526064016105d5565b61140c61140736839003830183611a5f565b61170a565b8060006114198282611b56565b9050507fe04232512a5cb82c08e0f9b1f51432930cd7a0b7ea9f9f916f080cb0b4ac644b81604051610c139190611d5e565b73ffffffffffffffffffffffffffffffffffffffff818116600090815260066020526040812054909116156114dc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600f60248201527f416c72656164792063726561746564000000000000000000000000000000000060448201526064016105d5565b60075473ffffffffffffffffffffffffffffffffffffffff1661155b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f506c7567696e206465706c6f796572206e6f742073657400000000000000000060448201526064016105d5565b600754600354600480546005546040517f0b0e157f00000000000000000000000000000000000000000000000000000000815260009573ffffffffffffffffffffffffffffffffffffffff90811695630b0e157f956115e8958b957f00000000000000000000000000000000000000000000000000000000000000009530958c9581169492169101611e07565b6020604051808303816000875af1158015611607573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061162b9190611a05565b6002546040517f64fae8a900000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff91821660048201529192508216906364fae8a990602401600060405180830381600087803b15801561169a57600080fd5b505af11580156116ae573d6000803e3d6000fd5b5050505073ffffffffffffffffffffffffffffffffffffffff928316600090815260066020526040902080547fffffffffffffffffffffffff000000000000000000000000000000000000000016938216939093179092555090565b60c08101516020820151825161ffff9283169161172c91908416908416611f05565b6117369190611f05565b111561179e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f4d6178206665652065786365656465640000000000000000000000000000000060448201526064016105d5565b608081015161ffff16158015906117bc575060a081015161ffff1615155b611822576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f47616d6d6173206d757374206265203e2030000000000000000000000000000060448201526064016105d5565b50565b73ffffffffffffffffffffffffffffffffffffffff8116811461182257600080fd5b60008060006060848603121561185c57600080fd5b833561186781611825565b9250602084013561187781611825565b9150604084013561188781611825565b809150509250925092565b600080600080600080600060c0888a0312156118ad57600080fd5b87356118b881611825565b965060208801356118c881611825565b955060408801356118d881611825565b945060608801356118e881611825565b935060808801356118f881611825565b925060a088013567ffffffffffffffff8082111561191557600080fd5b818a0191508a601f83011261192957600080fd5b81358181111561193857600080fd5b8b602082850101111561194a57600080fd5b60208301945080935050505092959891949750929550565b6000806040838503121561197557600080fd5b823561198081611825565b946020939093013593505050565b6000602082840312156119a057600080fd5b81356119ab81611825565b9392505050565b600060e082840312156119c457600080fd5b50919050565b6000602082840312156119dc57600080fd5b5051919050565b6000602082840312156119f557600080fd5b815180151581146119ab57600080fd5b600060208284031215611a1757600080fd5b81516119ab81611825565b61ffff8116811461182257600080fd5b8035611a3d81611a22565b919050565b63ffffffff8116811461182257600080fd5b8035611a3d81611a42565b600060e08284031215611a7157600080fd5b60405160e0810181811067ffffffffffffffff82111715611abb577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604052611ac783611a32565b8152611ad560208401611a32565b6020820152611ae660408401611a54565b6040820152611af760608401611a54565b6060820152611b0860808401611a32565b6080820152611b1960a08401611a32565b60a0820152611b2a60c08401611a32565b60c08201529392505050565b60008135611b4381611a22565b92915050565b60008135611b4381611a42565b8135611b6181611a22565b61ffff811690508154817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000082161783556020840135611b9f81611a22565b63ffff00008160101b16905080837fffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000008416171784556040850135611be281611a42565b67ffffffff000000008160201b16847fffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000851617831717855550505050611c6a611c2d60608401611b49565b82547fffffffffffffffffffffffffffffffffffffffff00000000ffffffffffffffff1660409190911b6bffffffff000000000000000016178255565b611cb8611c7960808401611b36565b82547fffffffffffffffffffffffffffffffffffff0000ffffffffffffffffffffffff1660609190911b6dffff00000000000000000000000016178255565b611d08611cc760a08401611b36565b82547fffffffffffffffffffffffffffffffff0000ffffffffffffffffffffffffffff1660709190911b6fffff000000000000000000000000000016178255565b611d5a611d1760c08401611b36565b82547fffffffffffffffffffffffffffff0000ffffffffffffffffffffffffffffffff1660809190911b71ffff0000000000000000000000000000000016178255565b5050565b60e081018235611d6d81611a22565b61ffff9081168352602084013590611d8482611a22565b9081166020840152604084013590611d9b82611a42565b63ffffffff9182166040850152606085013591611db783611a42565b919091166060840152608084013590611dcf82611a22565b166080830152611de160a08401611a32565b61ffff1660a0830152611df660c08401611a32565b61ffff811660c08401525092915050565b60006101a08201905073ffffffffffffffffffffffffffffffffffffffff808a1683528089166020840152808816604084015250855461ffff8082166060850152808260101c16608085015263ffffffff808360201c1660a0860152611e7a60c08601828560401c1663ffffffff169052565b50611e9060e08501828460601c1661ffff169052565b611ea66101008501828460701c1661ffff169052565b611ebc6101208501828460801c1661ffff169052565b505073ffffffffffffffffffffffffffffffffffffffff85166101408301528361016083015261087861018083018473ffffffffffffffffffffffffffffffffffffffff169052565b80820180821115611b43577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fdfea164736f6c6343000814000a000000000000000000000000946190a702b591ed4770531038fbd28f17a859fe
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106101515760003560e01c8063a7b64b04116100cd578063cdef16f611610081578063e1d03ecf11610066578063e1d03ecf146103d5578063f20cdc1a146103f5578063f718949a1461041557600080fd5b8063cdef16f61461038c578063d2cfc1f0146103c257600080fd5b8063b271039e116100b2578063b271039e14610332578063c3da797814610352578063cddff2691461036557600080fd5b8063a7b64b04146102f8578063b001f6181461031f57600080fd5b806364fae8a9116101245780638d5ef8d1116101095780638d5ef8d1146102ae578063915d61c2146102c15780639b21f9ae146102d857600080fd5b806364fae8a91461027b5780638a2ade581461028e57600080fd5b80630624e2be146101565780631d0338d9146101935780632e04369a146101a65780634e09a96a146101bb575b600080fd5b610169610164366004611847565b610428565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b6101696101a1366004611892565b61082b565b6101b96101b4366004611962565b610884565b005b6000546102339061ffff8082169162010000810482169163ffffffff6401000000008304811692680100000000000000008104909116916c0100000000000000000000000082048116916e01000000000000000000000000000081048216917001000000000000000000000000000000009091041687565b6040805161ffff9889168152968816602088015263ffffffff9586169087015293909216606085015284166080840152831660a08301529190911660c082015260e00161018a565b6101b961028936600461198e565b610a43565b6001546101699073ffffffffffffffffffffffffffffffffffffffff1681565b6101b96102bc366004611847565b610c1e565b6102ca60045481565b60405190815260200161018a565b6002546101699073ffffffffffffffffffffffffffffffffffffffff1681565b6101697f000000000000000000000000946190a702b591ed4770531038fbd28f17a859fe81565b6101b961032d36600461198e565b610c65565b6007546101699073ffffffffffffffffffffffffffffffffffffffff1681565b6101b961036036600461198e565b610e39565b6102ca7f267da724c255813ae00f4522fe843cb70148a4b8099cbc5af64f9a4151e55ed681565b61016961039a36600461198e565b60066020526000908152604090205473ffffffffffffffffffffffffffffffffffffffff1681565b6101b96103d036600461198e565b61100d565b6003546101699073ffffffffffffffffffffffffffffffffffffffff1681565b6005546101699073ffffffffffffffffffffffffffffffffffffffff1681565b6101b96104233660046119b2565b6112bb565b60007f000000000000000000000000946190a702b591ed4770531038fbd28f17a859fe3373ffffffffffffffffffffffffffffffffffffffff8416148061057357508073ffffffffffffffffffffffffffffffffffffffff1663e8ae2b698273ffffffffffffffffffffffffffffffffffffffff1663b500a48b6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156104d1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104f591906119ca565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b1681526004810191909152336024820152604401602060405180830381865afa15801561054f573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061057391906119e3565b6105de576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c79206465706c6f796572206f722061646d696e0000000000000000000060448201526064015b60405180910390fd5b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff160361061657600080fd5b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1610610650578385610653565b84845b909550935073ffffffffffffffffffffffffffffffffffffffff851661067857600080fd5b73ffffffffffffffffffffffffffffffffffffffff83166106f5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f437573746f6d20706f6f6c206465706c6f79657220697320726571756972656460448201526064016105d5565b6040517f23da36cc00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff848116600483015286811660248301528581166044830152600091908316906323da36cc90606401602060405180830381865afa158015610775573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107999190611a05565b905073ffffffffffffffffffffffffffffffffffffffff8116610818576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f506f6f6c206e6f7420657869737400000000000000000000000000000000000060448201526064016105d5565b6108218161144b565b9695505050505050565b60003373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000946190a702b591ed4770531038fbd28f17a859fe161461086f57600080fd5b6108788861144b565b98975050505050505050565b6040517fe8ae2b690000000000000000000000000000000000000000000000000000000081527f267da724c255813ae00f4522fe843cb70148a4b8099cbc5af64f9a4151e55ed660048201523360248201527f000000000000000000000000946190a702b591ed4770531038fbd28f17a859fe73ffffffffffffffffffffffffffffffffffffffff169063e8ae2b6990604401602060405180830381865afa158015610934573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061095891906119e3565b6109be576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f4f6e6c792061646d696e6973747261746f72000000000000000000000000000060448201526064016105d5565b600380547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8416908117909155600482905560408051918252602082018390527f2a6990173d4d27e6fc9962c340d27067d1a6bb7aeefbc291b62a21d7faf0d920910160405180910390a15050565b6040517fe8ae2b690000000000000000000000000000000000000000000000000000000081527f267da724c255813ae00f4522fe843cb70148a4b8099cbc5af64f9a4151e55ed660048201523360248201527f000000000000000000000000946190a702b591ed4770531038fbd28f17a859fe73ffffffffffffffffffffffffffffffffffffffff169063e8ae2b6990604401602060405180830381865afa158015610af3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b1791906119e3565b610b7d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f4f6e6c792061646d696e6973747261746f72000000000000000000000000000060448201526064016105d5565b60025473ffffffffffffffffffffffffffffffffffffffff808316911603610ba457600080fd5b600280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040519081527f9c2a61186234594f572ba9fd3d6137c9e751c20d5cad21e5c4bf008a768b3657906020015b60405180910390a150565b3373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000946190a702b591ed4770531038fbd28f17a859fe1614610c6057600080fd5b505050565b6040517fe8ae2b690000000000000000000000000000000000000000000000000000000081527f267da724c255813ae00f4522fe843cb70148a4b8099cbc5af64f9a4151e55ed660048201523360248201527f000000000000000000000000946190a702b591ed4770531038fbd28f17a859fe73ffffffffffffffffffffffffffffffffffffffff169063e8ae2b6990604401602060405180830381865afa158015610d15573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d3991906119e3565b610d9f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f4f6e6c792061646d696e6973747261746f72000000000000000000000000000060448201526064016105d5565b60015473ffffffffffffffffffffffffffffffffffffffff808316911603610dc657600080fd5b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040519081527f56b9e8342f530796ceed0d5529abdcdeae6e4f2ac1dc456ceb73bbda898e0cd390602001610c13565b6040517fe8ae2b690000000000000000000000000000000000000000000000000000000081527f267da724c255813ae00f4522fe843cb70148a4b8099cbc5af64f9a4151e55ed660048201523360248201527f000000000000000000000000946190a702b591ed4770531038fbd28f17a859fe73ffffffffffffffffffffffffffffffffffffffff169063e8ae2b6990604401602060405180830381865afa158015610ee9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f0d91906119e3565b610f73576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f4f6e6c792061646d696e6973747261746f72000000000000000000000000000060448201526064016105d5565b60055473ffffffffffffffffffffffffffffffffffffffff808316911603610f9a57600080fd5b600580547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040519081527f3b1f0d57f07483280d598ef402c5b2b96be1a42e65b21992bdafea3476b6532790602001610c13565b6040517fe8ae2b690000000000000000000000000000000000000000000000000000000081527f267da724c255813ae00f4522fe843cb70148a4b8099cbc5af64f9a4151e55ed660048201523360248201527f000000000000000000000000946190a702b591ed4770531038fbd28f17a859fe73ffffffffffffffffffffffffffffffffffffffff169063e8ae2b6990604401602060405180830381865afa1580156110bd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110e191906119e3565b611147576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f4f6e6c792061646d696e6973747261746f72000000000000000000000000000060448201526064016105d5565b73ffffffffffffffffffffffffffffffffffffffff81166111c4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f496e76616c6964206465706c6f7965722061646472657373000000000000000060448201526064016105d5565b60075473ffffffffffffffffffffffffffffffffffffffff808316911603611248576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f53616d65206465706c6f7965722061646472657373000000000000000000000060448201526064016105d5565b600780547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040519081527ffc38c91ab5781475eacf5b1c697bb748459ee6ee1a09876b34d955db0808983690602001610c13565b6040517fe8ae2b690000000000000000000000000000000000000000000000000000000081527f267da724c255813ae00f4522fe843cb70148a4b8099cbc5af64f9a4151e55ed660048201523360248201527f000000000000000000000000946190a702b591ed4770531038fbd28f17a859fe73ffffffffffffffffffffffffffffffffffffffff169063e8ae2b6990604401602060405180830381865afa15801561136b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061138f91906119e3565b6113f5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f4f6e6c792061646d696e6973747261746f72000000000000000000000000000060448201526064016105d5565b61140c61140736839003830183611a5f565b61170a565b8060006114198282611b56565b9050507fe04232512a5cb82c08e0f9b1f51432930cd7a0b7ea9f9f916f080cb0b4ac644b81604051610c139190611d5e565b73ffffffffffffffffffffffffffffffffffffffff818116600090815260066020526040812054909116156114dc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600f60248201527f416c72656164792063726561746564000000000000000000000000000000000060448201526064016105d5565b60075473ffffffffffffffffffffffffffffffffffffffff1661155b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f506c7567696e206465706c6f796572206e6f742073657400000000000000000060448201526064016105d5565b600754600354600480546005546040517f0b0e157f00000000000000000000000000000000000000000000000000000000815260009573ffffffffffffffffffffffffffffffffffffffff90811695630b0e157f956115e8958b957f000000000000000000000000946190a702b591ed4770531038fbd28f17a859fe9530958c9581169492169101611e07565b6020604051808303816000875af1158015611607573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061162b9190611a05565b6002546040517f64fae8a900000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff91821660048201529192508216906364fae8a990602401600060405180830381600087803b15801561169a57600080fd5b505af11580156116ae573d6000803e3d6000fd5b5050505073ffffffffffffffffffffffffffffffffffffffff928316600090815260066020526040902080547fffffffffffffffffffffffff000000000000000000000000000000000000000016938216939093179092555090565b60c08101516020820151825161ffff9283169161172c91908416908416611f05565b6117369190611f05565b111561179e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f4d6178206665652065786365656465640000000000000000000000000000000060448201526064016105d5565b608081015161ffff16158015906117bc575060a081015161ffff1615155b611822576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f47616d6d6173206d757374206265203e2030000000000000000000000000000060448201526064016105d5565b50565b73ffffffffffffffffffffffffffffffffffffffff8116811461182257600080fd5b60008060006060848603121561185c57600080fd5b833561186781611825565b9250602084013561187781611825565b9150604084013561188781611825565b809150509250925092565b600080600080600080600060c0888a0312156118ad57600080fd5b87356118b881611825565b965060208801356118c881611825565b955060408801356118d881611825565b945060608801356118e881611825565b935060808801356118f881611825565b925060a088013567ffffffffffffffff8082111561191557600080fd5b818a0191508a601f83011261192957600080fd5b81358181111561193857600080fd5b8b602082850101111561194a57600080fd5b60208301945080935050505092959891949750929550565b6000806040838503121561197557600080fd5b823561198081611825565b946020939093013593505050565b6000602082840312156119a057600080fd5b81356119ab81611825565b9392505050565b600060e082840312156119c457600080fd5b50919050565b6000602082840312156119dc57600080fd5b5051919050565b6000602082840312156119f557600080fd5b815180151581146119ab57600080fd5b600060208284031215611a1757600080fd5b81516119ab81611825565b61ffff8116811461182257600080fd5b8035611a3d81611a22565b919050565b63ffffffff8116811461182257600080fd5b8035611a3d81611a42565b600060e08284031215611a7157600080fd5b60405160e0810181811067ffffffffffffffff82111715611abb577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604052611ac783611a32565b8152611ad560208401611a32565b6020820152611ae660408401611a54565b6040820152611af760608401611a54565b6060820152611b0860808401611a32565b6080820152611b1960a08401611a32565b60a0820152611b2a60c08401611a32565b60c08201529392505050565b60008135611b4381611a22565b92915050565b60008135611b4381611a42565b8135611b6181611a22565b61ffff811690508154817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000082161783556020840135611b9f81611a22565b63ffff00008160101b16905080837fffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000008416171784556040850135611be281611a42565b67ffffffff000000008160201b16847fffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000851617831717855550505050611c6a611c2d60608401611b49565b82547fffffffffffffffffffffffffffffffffffffffff00000000ffffffffffffffff1660409190911b6bffffffff000000000000000016178255565b611cb8611c7960808401611b36565b82547fffffffffffffffffffffffffffffffffffff0000ffffffffffffffffffffffff1660609190911b6dffff00000000000000000000000016178255565b611d08611cc760a08401611b36565b82547fffffffffffffffffffffffffffffffff0000ffffffffffffffffffffffffffff1660709190911b6fffff000000000000000000000000000016178255565b611d5a611d1760c08401611b36565b82547fffffffffffffffffffffffffffff0000ffffffffffffffffffffffffffffffff1660809190911b71ffff0000000000000000000000000000000016178255565b5050565b60e081018235611d6d81611a22565b61ffff9081168352602084013590611d8482611a22565b9081166020840152604084013590611d9b82611a42565b63ffffffff9182166040850152606085013591611db783611a42565b919091166060840152608084013590611dcf82611a22565b166080830152611de160a08401611a32565b61ffff1660a0830152611df660c08401611a32565b61ffff811660c08401525092915050565b60006101a08201905073ffffffffffffffffffffffffffffffffffffffff808a1683528089166020840152808816604084015250855461ffff8082166060850152808260101c16608085015263ffffffff808360201c1660a0860152611e7a60c08601828560401c1663ffffffff169052565b50611e9060e08501828460601c1661ffff169052565b611ea66101008501828460701c1661ffff169052565b611ebc6101208501828460801c1661ffff169052565b505073ffffffffffffffffffffffffffffffffffffffff85166101408301528361016083015261087861018083018473ffffffffffffffffffffffffffffffffffffffff169052565b80820180821115611b43577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fdfea164736f6c6343000814000a
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000946190a702b591ed4770531038fbd28f17a859fe
-----Decoded View---------------
Arg [0] : _algebraFactory (address): 0x946190A702B591Ed4770531038Fbd28f17a859fE
-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 000000000000000000000000946190a702b591ed4770531038fbd28f17a859fe
Loading...
Loading
Loading...
Loading
Net Worth in USD
$0.00
Net Worth in ETH
0
Multichain Portfolio | 33 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.