Overview
S Balance
0 S
S Value
-More Info
Private Name Tags
ContractCreator
Loading...
Loading
Contract Name:
AlgebraCommunityVault
Compiler Version
v0.8.20+commit.a1b79de6
Optimization Enabled:
Yes with 800 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 './libraries/SafeTransfer.sol'; import './libraries/FullMath.sol'; import './interfaces/IAlgebraFactory.sol'; import './interfaces/vault/IAlgebraCommunityVault.sol'; /// @title Algebra community fee vault /// @notice Community fee from pools is sent here, if it is enabled /// @dev Role system is used to withdraw tokens /// @dev Version: Algebra Integral 1.0 contract AlgebraCommunityVault is IAlgebraCommunityVault { /// @dev The role can be granted in AlgebraFactory bytes32 public constant COMMUNITY_FEE_WITHDRAWER_ROLE = keccak256('COMMUNITY_FEE_WITHDRAWER'); /// @dev The role can be granted in AlgebraFactory bytes32 public constant COMMUNITY_FEE_VAULT_ADMINISTRATOR = keccak256('COMMUNITY_FEE_VAULT_ADMINISTRATOR'); address private immutable factory; /// @notice Address to which community fees are sent from vault address public communityFeeReceiver; /// @notice The percentage of the protocol fee that Algebra will receive /// @dev Value in thousandths,i.e. 1e-3 uint16 public algebraFee; /// @notice Represents whether there is a new Algebra fee proposal or not bool public hasNewAlgebraFeeProposal; /// @notice Suggested Algebra fee value uint16 public proposedNewAlgebraFee; /// @notice Address of recipient Algebra part of community fee address public algebraFeeReceiver; /// @notice Address of Algebra fee manager address public algebraFeeManager; address private _pendingAlgebraFeeManager; uint16 private constant ALGEBRA_FEE_DENOMINATOR = 1000; modifier onlyAdministrator() { require(IAlgebraFactory(factory).hasRoleOrOwner(COMMUNITY_FEE_VAULT_ADMINISTRATOR, msg.sender), 'only administrator'); _; } modifier onlyWithdrawer() { require(msg.sender == algebraFeeManager || IAlgebraFactory(factory).hasRoleOrOwner(COMMUNITY_FEE_WITHDRAWER_ROLE, msg.sender), 'only withdrawer'); _; } modifier onlyAlgebraFeeManager() { require(msg.sender == algebraFeeManager, 'only algebra fee manager'); _; } constructor(address _factory, address _algebraFeeManager) { (factory, algebraFeeManager) = (_factory, _algebraFeeManager); } /// @inheritdoc IAlgebraCommunityVault function withdraw(address token, uint256 amount) external override onlyWithdrawer { (uint16 _algebraFee, address _algebraFeeReceiver, address _communityFeeReceiver) = _readAndVerifyWithdrawSettings(); _withdraw(token, _communityFeeReceiver, amount, _algebraFee, _algebraFeeReceiver); } /// @inheritdoc IAlgebraCommunityVault function withdrawTokens(WithdrawTokensParams[] calldata params) external override onlyWithdrawer { uint256 paramsLength = params.length; (uint16 _algebraFee, address _algebraFeeReceiver, address _communityFeeReceiver) = _readAndVerifyWithdrawSettings(); unchecked { for (uint256 i; i < paramsLength; ++i) _withdraw(params[i].token, _communityFeeReceiver, params[i].amount, _algebraFee, _algebraFeeReceiver); } } function _readAndVerifyWithdrawSettings() private view returns (uint16 _algebraFee, address _algebraFeeReceiver, address _communityFeeReceiver) { (_algebraFee, _algebraFeeReceiver, _communityFeeReceiver) = (algebraFee, algebraFeeReceiver, communityFeeReceiver); if (_algebraFee != 0) require(_algebraFeeReceiver != address(0), 'invalid algebra fee receiver'); require(_communityFeeReceiver != address(0), 'invalid receiver'); } function _withdraw(address token, address to, uint256 amount, uint16 _algebraFee, address _algebraFeeReceiver) private { uint256 withdrawAmount = amount; if (_algebraFee != 0) { uint256 algebraFeeAmount = FullMath.mulDivRoundingUp(withdrawAmount, _algebraFee, ALGEBRA_FEE_DENOMINATOR); withdrawAmount -= algebraFeeAmount; SafeTransfer.safeTransfer(token, _algebraFeeReceiver, algebraFeeAmount); emit AlgebraTokensWithdrawal(token, _algebraFeeReceiver, algebraFeeAmount); } SafeTransfer.safeTransfer(token, to, withdrawAmount); emit TokensWithdrawal(token, to, withdrawAmount); } // ### algebra factory owner permissioned actions ### /// @inheritdoc IAlgebraCommunityVault function acceptAlgebraFeeChangeProposal(uint16 newAlgebraFee) external override onlyAdministrator { require(hasNewAlgebraFeeProposal, 'not proposed'); require(newAlgebraFee == proposedNewAlgebraFee, 'invalid new fee'); // note that the new value will be used for previously accumulated tokens that have not yet been withdrawn algebraFee = newAlgebraFee; (proposedNewAlgebraFee, hasNewAlgebraFeeProposal) = (0, false); emit AlgebraFee(newAlgebraFee); } /// @inheritdoc IAlgebraCommunityVault function changeCommunityFeeReceiver(address newCommunityFeeReceiver) external override onlyAdministrator { require(newCommunityFeeReceiver != address(0)); require(newCommunityFeeReceiver != communityFeeReceiver); communityFeeReceiver = newCommunityFeeReceiver; emit CommunityFeeReceiver(newCommunityFeeReceiver); } // ### algebra fee manager permissioned actions ### /// @inheritdoc IAlgebraCommunityVault function transferAlgebraFeeManagerRole(address _newAlgebraFeeManager) external override onlyAlgebraFeeManager { _pendingAlgebraFeeManager = _newAlgebraFeeManager; emit PendingAlgebraFeeManager(_newAlgebraFeeManager); } /// @inheritdoc IAlgebraCommunityVault function acceptAlgebraFeeManagerRole() external override { require(msg.sender == _pendingAlgebraFeeManager); (_pendingAlgebraFeeManager, algebraFeeManager) = (address(0), msg.sender); emit AlgebraFeeManager(msg.sender); } /// @inheritdoc IAlgebraCommunityVault function proposeAlgebraFeeChange(uint16 newAlgebraFee) external override onlyAlgebraFeeManager { require(newAlgebraFee <= ALGEBRA_FEE_DENOMINATOR); require(newAlgebraFee != proposedNewAlgebraFee && newAlgebraFee != algebraFee); (proposedNewAlgebraFee, hasNewAlgebraFeeProposal) = (newAlgebraFee, true); emit AlgebraFeeProposal(newAlgebraFee); } /// @inheritdoc IAlgebraCommunityVault function cancelAlgebraFeeChangeProposal() external override onlyAlgebraFeeManager { (proposedNewAlgebraFee, hasNewAlgebraFeeProposal) = (0, false); emit CancelAlgebraFeeProposal(); } /// @inheritdoc IAlgebraCommunityVault function changeAlgebraFeeReceiver(address newAlgebraFeeReceiver) external override onlyAlgebraFeeManager { require(newAlgebraFeeReceiver != address(0)); require(newAlgebraFeeReceiver != algebraFeeReceiver); algebraFeeReceiver = newAlgebraFeeReceiver; emit AlgebraFeeReceiver(newAlgebraFeeReceiver); } }
// 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 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 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 /// @param pool the address of liquidity 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 /// @return communityFeeVault the address of communityFeeVault function defaultConfigurationForPool( address pool ) external view returns (uint16 communityFee, int24 tickSpacing, uint16 fee, address communityFeeVault); /// @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 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 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 /// @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) external returns (address pool); /// @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; function getPair(address tokenA, address tokenB) external view returns (address pair); }
// 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 is needed if the plugin should be automatically created and connected to each new pool interface IAlgebraPluginFactory { /// @notice Deploys new plugin contract for pool /// @param pool The address of the pool for which the new plugin will be created /// @param token0 First token of the pool /// @param token1 Second token of the pool /// @return New plugin address function createPlugin(address pool, address token0, address token1) external returns (address); }
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity >=0.8.4; /// @title Errors emitted by a pool /// @notice Contains custom errors emitted by the pool /// @dev Custom errors are separated from the common pool interface for compatibility with older versions of Solidity interface IAlgebraPoolErrors { // #### pool errors #### /// @notice Emitted by the reentrancy guard error locked(); /// @notice Emitted if arithmetic error occurred error arithmeticError(); /// @notice Emitted if an attempt is made to initialize the pool twice error alreadyInitialized(); /// @notice Emitted if an attempt is made to mint or swap in uninitialized pool error notInitialized(); /// @notice Emitted if 0 is passed as amountRequired to swap function error zeroAmountRequired(); /// @notice Emitted if invalid amount is passed as amountRequired to swap function error invalidAmountRequired(); /// @notice Emitted if the pool received fewer tokens than it should have error insufficientInputAmount(); /// @notice Emitted if there was an attempt to mint zero liquidity error zeroLiquidityDesired(); /// @notice Emitted if actual amount of liquidity is zero (due to insufficient amount of tokens received) error zeroLiquidityActual(); /// @notice Emitted if the pool received fewer tokens0 after flash than it should have error flashInsufficientPaid0(); /// @notice Emitted if the pool received fewer tokens1 after flash than it should have error flashInsufficientPaid1(); /// @notice Emitted if limitSqrtPrice param is incorrect error invalidLimitSqrtPrice(); /// @notice Tick must be divisible by tickspacing error tickIsNotSpaced(); /// @notice Emitted if a method is called that is accessible only to the factory owner or dedicated role error notAllowed(); /// @notice Emitted if new tick spacing exceeds max allowed value error invalidNewTickSpacing(); /// @notice Emitted if new community fee exceeds max allowed value error invalidNewCommunityFee(); /// @notice Emitted if an attempt is made to manually change the fee value, but dynamic fee is enabled error dynamicFeeActive(); /// @notice Emitted if an attempt is made by plugin to change the fee value, but dynamic fee is disabled error dynamicFeeDisabled(); /// @notice Emitted if an attempt is made to change the plugin configuration, but the plugin is not connected error pluginIsNotConnected(); /// @notice Emitted if a plugin returns invalid selector after hook call /// @param expectedSelector The expected selector error invalidHookResponse(bytes4 expectedSelector); // #### LiquidityMath errors #### /// @notice Emitted if liquidity underflows error liquiditySub(); /// @notice Emitted if liquidity overflows error liquidityAdd(); // #### TickManagement errors #### /// @notice Emitted if the topTick param not greater then the bottomTick param error topTickLowerOrEqBottomTick(); /// @notice Emitted if the bottomTick param is lower than min allowed value error bottomTickLowerThanMIN(); /// @notice Emitted if the topTick param is greater than max allowed value error topTickAboveMAX(); /// @notice Emitted if the liquidity value associated with the tick exceeds MAX_LIQUIDITY_PER_TICK error liquidityOverflow(); /// @notice Emitted if an attempt is made to interact with an uninitialized tick error tickIsNotInitialized(); /// @notice Emitted if there is an attempt to insert a new tick into the list of ticks with incorrect indexes of the previous and next ticks error tickInvalidLinks(); // #### SafeTransfer errors #### /// @notice Emitted if token transfer failed internally error transferFailed(); // #### TickMath errors #### /// @notice Emitted if tick is greater than the maximum or less than the minimum allowed value error tickOutOfRange(); /// @notice Emitted if price is greater than the maximum or less than the minimum allowed value error priceOutOfRange(); }
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity >=0.5.0; /// @title The interface for the Algebra community fee vault /// @notice Community fee from pools is sent here, if it is enabled /// @dev Version: Algebra Integral interface IAlgebraCommunityVault { /// @notice Event emitted when a fees has been claimed /// @param token The address of token fee /// @param to The address where claimed rewards were sent to /// @param amount The amount of fees tokens claimed by communityFeeReceiver event TokensWithdrawal(address indexed token, address indexed to, uint256 amount); /// @notice Event emitted when a fees has been claimed /// @param token The address of token fee /// @param to The address where claimed rewards were sent to /// @param amount The amount of fees tokens claimed by Algebra event AlgebraTokensWithdrawal(address indexed token, address indexed to, uint256 amount); /// @notice Emitted when a AlgebraFeeReceiver address changed /// @param newAlgebraFeeReceiver New Algebra fee receiver address event AlgebraFeeReceiver(address newAlgebraFeeReceiver); /// @notice Emitted when a AlgebraFeeManager address change proposed /// @param pendingAlgebraFeeManager New pending Algebra fee manager address event PendingAlgebraFeeManager(address pendingAlgebraFeeManager); /// @notice Emitted when a new Algebra fee value proposed /// @param proposedNewAlgebraFee The new proposed Algebra fee value event AlgebraFeeProposal(uint16 proposedNewAlgebraFee); /// @notice Emitted when a Algebra fee proposal canceled event CancelAlgebraFeeProposal(); /// @notice Emitted when a AlgebraFeeManager address changed /// @param newAlgebraFeeManager New Algebra fee manager address event AlgebraFeeManager(address newAlgebraFeeManager); /// @notice Emitted when the Algebra fee is changed /// @param newAlgebraFee The new Algebra fee value event AlgebraFee(uint16 newAlgebraFee); /// @notice Emitted when a CommunityFeeReceiver address changed /// @param newCommunityFeeReceiver New fee receiver address event CommunityFeeReceiver(address newCommunityFeeReceiver); /// @notice Withdraw protocol fees from vault /// @dev Can only be called by algebraFeeManager or communityFeeReceiver /// @param token The token address /// @param amount The amount of token function withdraw(address token, uint256 amount) external; struct WithdrawTokensParams { address token; uint256 amount; } /// @notice Withdraw protocol fees from vault. Used to claim fees for multiple tokens /// @dev Can be called by algebraFeeManager or communityFeeReceiver /// @param params Array of WithdrawTokensParams objects containing token addresses and amounts to withdraw function withdrawTokens(WithdrawTokensParams[] calldata params) external; // ### algebra factory owner permissioned actions ### /// @notice Accepts the proposed new Algebra fee /// @dev Can only be called by the factory owner. /// The new value will also be used for previously accumulated tokens that have not yet been withdrawn /// @param newAlgebraFee New Algebra fee value function acceptAlgebraFeeChangeProposal(uint16 newAlgebraFee) external; /// @notice Change community fee receiver address /// @dev Can only be called by the factory owner /// @param newCommunityFeeReceiver New community fee receiver address function changeCommunityFeeReceiver(address newCommunityFeeReceiver) external; // ### algebra fee manager permissioned actions ### /// @notice Transfers Algebra fee manager role /// @param _newAlgebraFeeManager new Algebra fee manager address function transferAlgebraFeeManagerRole(address _newAlgebraFeeManager) external; /// @notice accept Algebra FeeManager role function acceptAlgebraFeeManagerRole() external; /// @notice Proposes new Algebra fee value for protocol /// @dev the new value will also be used for previously accumulated tokens that have not yet been withdrawn /// @param newAlgebraFee new Algebra fee value function proposeAlgebraFeeChange(uint16 newAlgebraFee) external; /// @notice Cancels Algebra fee change proposal function cancelAlgebraFeeChangeProposal() external; /// @notice Change Algebra community fee part receiver /// @param newAlgebraFeeReceiver The address of new Algebra fee receiver function changeAlgebraFeeReceiver(address newAlgebraFeeReceiver) 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) external returns (address communityFeeVault); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /// @title Contains 512-bit math functions /// @notice Facilitates multiplication and division that can have overflow of an intermediate value without any loss of precision /// @dev Handles "phantom overflow" i.e., allows multiplication and division where an intermediate value overflows 256 bits library FullMath { /// @notice Calculates floor(a×b÷denominator) with full precision. Throws if result overflows a uint256 or denominator == 0 /// @param a The multiplicand /// @param b The multiplier /// @param denominator The divisor /// @return result The 256-bit result /// @dev Credit to Remco Bloemen under MIT license https://xn--2-umb.com/21/muldiv function mulDiv(uint256 a, uint256 b, uint256 denominator) internal pure returns (uint256 result) { unchecked { // 512-bit multiply [prod1 prod0] = a * b // Compute the product mod 2**256 and mod 2**256 - 1 // then use the Chinese Remainder Theorem to reconstruct // the 512 bit result. The result is stored in two 256 // variables such that product = prod1 * 2**256 + prod0 uint256 prod0 = a * b; // Least significant 256 bits of the product uint256 prod1; // Most significant 256 bits of the product assembly { let mm := mulmod(a, b, not(0)) prod1 := sub(sub(mm, prod0), lt(mm, prod0)) } // Make sure the result is less than 2**256. // Also prevents denominator == 0 require(denominator > prod1); // Handle non-overflow cases, 256 by 256 division if (prod1 == 0) { assembly { result := div(prod0, denominator) } return result; } /////////////////////////////////////////////// // 512 by 256 division. /////////////////////////////////////////////// // Make division exact by subtracting the remainder from [prod1 prod0] // Compute remainder using mulmod // Subtract 256 bit remainder from 512 bit number assembly { let remainder := mulmod(a, b, denominator) prod1 := sub(prod1, gt(remainder, prod0)) prod0 := sub(prod0, remainder) } // Factor powers of two out of denominator // Compute largest power of two divisor of denominator. // Always >= 1. uint256 twos = (0 - denominator) & denominator; // Divide denominator by power of two assembly { denominator := div(denominator, twos) } // Divide [prod1 prod0] by the factors of two assembly { prod0 := div(prod0, twos) } // Shift in bits from prod1 into prod0. For this we need // to flip `twos` such that it is 2**256 / twos. // If twos is zero, then it becomes one assembly { twos := add(div(sub(0, twos), twos), 1) } prod0 |= prod1 * twos; // Invert denominator mod 2**256 // Now that denominator is an odd number, it has an inverse // modulo 2**256 such that denominator * inv = 1 mod 2**256. // Compute the inverse by starting with a seed that is correct // correct for four bits. That is, denominator * inv = 1 mod 2**4 uint256 inv = (3 * denominator) ^ 2; // Now use Newton-Raphson iteration to improve the precision. // Thanks to Hensel's lifting lemma, this also works in modular // arithmetic, doubling the correct bits in each step. inv *= 2 - denominator * inv; // inverse mod 2**8 inv *= 2 - denominator * inv; // inverse mod 2**16 inv *= 2 - denominator * inv; // inverse mod 2**32 inv *= 2 - denominator * inv; // inverse mod 2**64 inv *= 2 - denominator * inv; // inverse mod 2**128 inv *= 2 - denominator * inv; // inverse mod 2**256 // Because the division is now exact we can divide by multiplying // with the modular inverse of denominator. This will give us the // correct result modulo 2**256. Since the preconditions guarantee // that the outcome is less than 2**256, this is the final result. // We don't need to compute the high bits of the result and prod1 // is no longer required. result = prod0 * inv; return result; } } /// @notice Calculates ceil(a×b÷denominator) with full precision. Throws if result overflows a uint256 or denominator == 0 /// @param a The multiplicand /// @param b The multiplier /// @param denominator The divisor /// @return result The 256-bit result function mulDivRoundingUp(uint256 a, uint256 b, uint256 denominator) internal pure returns (uint256 result) { unchecked { if (a == 0 || ((result = a * b) / a == b)) { require(denominator > 0); assembly { result := add(div(result, denominator), gt(mod(result, denominator), 0)) } } else { result = mulDiv(a, b, denominator); if (mulmod(a, b, denominator) > 0) { require(result < type(uint256).max); result++; } } } } /// @notice Returns ceil(x / y) /// @dev division by 0 has unspecified behavior, and must be checked externally /// @param x The dividend /// @param y The divisor /// @return z The quotient, ceil(x / y) function unsafeDivRoundingUp(uint256 x, uint256 y) internal pure returns (uint256 z) { assembly { z := add(div(x, y), gt(mod(x, y), 0)) } } }
// SPDX-License-Identifier: MIT pragma solidity >=0.8.4 <0.9.0; import '../interfaces/pool/IAlgebraPoolErrors.sol'; /// @title SafeTransfer /// @notice Safe ERC20 transfer library that gracefully handles missing return values. /// @dev Credit to Solmate under MIT license: https://github.com/transmissions11/solmate/blob/ed67feda67b24fdeff8ad1032360f0ee6047ba0a/src/utils/SafeTransferLib.sol /// @dev Please note that this library does not check if the token has a code! That responsibility is delegated to the caller. library SafeTransfer { /// @notice Transfers tokens to a recipient /// @dev Calls transfer on token contract, errors with transferFailed() if transfer fails /// @param token The contract address of the token which will be transferred /// @param to The recipient of the transfer /// @param amount The amount of the token to transfer function safeTransfer(address token, address to, uint256 amount) internal { bool success; assembly { let freeMemoryPointer := mload(0x40) // we will need to restore 0x40 slot mstore(0x00, 0xa9059cbb00000000000000000000000000000000000000000000000000000000) // "transfer(address,uint256)" selector mstore(0x04, and(to, 0xffffffffffffffffffffffffffffffffffffffff)) // append cleaned "to" address mstore(0x24, amount) // now we use 0x00 - 0x44 bytes (68), freeMemoryPointer is dirty success := call(gas(), token, 0, 0, 0x44, 0, 0x20) success := and( // set success to true if call isn't reverted and returned exactly 1 (can't just be non-zero data) or nothing or(and(eq(mload(0), 1), eq(returndatasize(), 32)), iszero(returndatasize())), success ) mstore(0x40, freeMemoryPointer) // restore the freeMemoryPointer } if (!success) revert IAlgebraPoolErrors.transferFailed(); } }
{ "evmVersion": "paris", "optimizer": { "enabled": true, "runs": 800 }, "metadata": { "bytecodeHash": "none" }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"address","name":"_factory","type":"address"},{"internalType":"address","name":"_algebraFeeManager","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"transferFailed","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint16","name":"newAlgebraFee","type":"uint16"}],"name":"AlgebraFee","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"newAlgebraFeeManager","type":"address"}],"name":"AlgebraFeeManager","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint16","name":"proposedNewAlgebraFee","type":"uint16"}],"name":"AlgebraFeeProposal","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"newAlgebraFeeReceiver","type":"address"}],"name":"AlgebraFeeReceiver","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"token","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"AlgebraTokensWithdrawal","type":"event"},{"anonymous":false,"inputs":[],"name":"CancelAlgebraFeeProposal","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"newCommunityFeeReceiver","type":"address"}],"name":"CommunityFeeReceiver","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"pendingAlgebraFeeManager","type":"address"}],"name":"PendingAlgebraFeeManager","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"token","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"TokensWithdrawal","type":"event"},{"inputs":[],"name":"COMMUNITY_FEE_VAULT_ADMINISTRATOR","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"COMMUNITY_FEE_WITHDRAWER_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"newAlgebraFee","type":"uint16"}],"name":"acceptAlgebraFeeChangeProposal","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"acceptAlgebraFeeManagerRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"algebraFee","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"algebraFeeManager","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"algebraFeeReceiver","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"cancelAlgebraFeeChangeProposal","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newAlgebraFeeReceiver","type":"address"}],"name":"changeAlgebraFeeReceiver","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newCommunityFeeReceiver","type":"address"}],"name":"changeCommunityFeeReceiver","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"communityFeeReceiver","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"hasNewAlgebraFeeProposal","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"newAlgebraFee","type":"uint16"}],"name":"proposeAlgebraFeeChange","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"proposedNewAlgebraFee","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_newAlgebraFeeManager","type":"address"}],"name":"transferAlgebraFeeManagerRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct IAlgebraCommunityVault.WithdrawTokensParams[]","name":"params","type":"tuple[]"}],"name":"withdrawTokens","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
60a060405234801561001057600080fd5b5060405161122338038061122383398101604081905261002f91610070565b600280546001600160a01b0319166001600160a01b03928316179055166080526100a3565b80516001600160a01b038116811461006b57600080fd5b919050565b6000806040838503121561008357600080fd5b61008c83610054565b915061009a60208401610054565b90509250929050565b6080516111506100d3600039600081816104fa01528181610819015281816109970152610aaa01526111506000f3fe608060405234801561001057600080fd5b506004361061011b5760003560e01c8063ad6129ac116100b2578063d17bc78311610081578063dfadc79411610066578063dfadc79414610291578063f3fef3a3146102a4578063ff3c43e1146102b757600080fd5b8063d17bc78314610276578063d9fb43531461027e57600080fd5b8063ad6129ac14610210578063b5f680ae14610218578063bbac3b8d1461022b578063c53b3fbe1461025257600080fd5b806350eea0c8116100ee57806350eea0c8146101ad57806362744405146101c05780639d754dde146101e85780639f856b8d146101fb57600080fd5b80631de4161314610120578063371abc951461015a5780634738761c1461018557806348a50fcf14610198575b600080fd5b6101477fb77a63f119f4dc2174dc6c76fc1a1565fa4f2b0dde50ed5c0465471cd9b331f681565b6040519081526020015b60405180910390f35b60005461016d906001600160a01b031681565b6040516001600160a01b039091168152602001610151565b60015461016d906001600160a01b031681565b6101ab6101a6366004610ff0565b6102ca565b005b6101ab6101bb366004610ff0565b6103ac565b6000546101d590600160b81b900461ffff1681565b60405161ffff9091168152602001610151565b60025461016d906001600160a01b031681565b6000546101d590600160a01b900461ffff1681565b6101ab610454565b6101ab610226366004610ff0565b6104bf565b6101477f63e58c34d94475ba3fc063e19800b940485850d84d09cd3c1f2c14192c559a6881565b60005461026690600160b01b900460ff1681565b6040519015158152602001610151565b6101ab610635565b6101ab61028c36600461100b565b6106c7565b6101ab61029f36600461102f565b6107ca565b6101ab6102b23660046110a4565b610948565b6101ab6102c536600461100b565b610a6f565b6002546001600160a01b031633146103295760405162461bcd60e51b815260206004820152601860248201527f6f6e6c7920616c676562726120666565206d616e61676572000000000000000060448201526064015b60405180910390fd5b6001600160a01b03811661033c57600080fd5b6001546001600160a01b039081169082160361035757600080fd5b600180546001600160a01b0319166001600160a01b0383169081179091556040519081527f34d1b5ef1c1c2c03a5000b91bef5c465790244c6751c794e5b45bed7657c38fd906020015b60405180910390a150565b6002546001600160a01b031633146104065760405162461bcd60e51b815260206004820152601860248201527f6f6e6c7920616c676562726120666565206d616e6167657200000000000000006044820152606401610320565b600380546001600160a01b0319166001600160a01b0383169081179091556040519081527fab6918ba7303f2f81e46e324b5f34af4bda562577c1da710e2034980fee1e82a906020016103a1565b6003546001600160a01b0316331461046b57600080fd5b60028054336001600160a01b031991821681179092556003805490911690556040519081527fecf97a11fb2f2bcc38d1b6881865ecc04405af2d8b953004c79b3ab398732d029060200160405180910390a1565b60405163e8ae2b6960e01b81527f63e58c34d94475ba3fc063e19800b940485850d84d09cd3c1f2c14192c559a6860048201523360248201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063e8ae2b6990604401602060405180830381865afa158015610549573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061056d91906110ce565b6105b95760405162461bcd60e51b815260206004820152601260248201527f6f6e6c792061646d696e6973747261746f7200000000000000000000000000006044820152606401610320565b6001600160a01b0381166105cc57600080fd5b6000546001600160a01b03908116908216036105e757600080fd5b600080546001600160a01b0319166001600160a01b0383169081179091556040519081527f2f4db788b994a5908051d68a2340153f49870447185a244d2326861e60cc4186906020016103a1565b6002546001600160a01b0316331461068f5760405162461bcd60e51b815260206004820152601860248201527f6f6e6c7920616c676562726120666565206d616e6167657200000000000000006044820152606401610320565b6000805462ffffff60b01b191681556040517f9f4bbade0736edbd2ec12c598bdac4573af13a3b57820ae4c7da5c61703eaaff9190a1565b6002546001600160a01b031633146107215760405162461bcd60e51b815260206004820152601860248201527f6f6e6c7920616c676562726120666565206d616e6167657200000000000000006044820152606401610320565b6103e861ffff8216111561073457600080fd5b60005461ffff828116600160b81b9092041614801590610764575060005461ffff828116600160a01b9092041614155b61076d57600080fd5b6000805461ffff8316600160b81b0262ffffff60b01b1990911617600160b01b1790556040517f2d6ac59d6da98f80c7ea481d17c670ea310b000fff5cf1732d94d93652dd25b7906103a190839061ffff91909116815260200190565b6002546001600160a01b031633148061088c575060405163e8ae2b6960e01b81527fb77a63f119f4dc2174dc6c76fc1a1565fa4f2b0dde50ed5c0465471cd9b331f660048201523360248201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063e8ae2b6990604401602060405180830381865afa158015610868573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061088c91906110ce565b6108ca5760405162461bcd60e51b815260206004820152600f60248201526e37b7363c903bb4ba34323930bbb2b960891b6044820152606401610320565b80600080806108d7610c94565b92509250925060005b8481101561093f576109378787838181106108fd576108fd6110f0565b6109139260206040909202019081019150610ff0565b83898985818110610926576109266110f0565b905060400201602001358787610d6a565b6001016108e0565b50505050505050565b6002546001600160a01b0316331480610a0a575060405163e8ae2b6960e01b81527fb77a63f119f4dc2174dc6c76fc1a1565fa4f2b0dde50ed5c0465471cd9b331f660048201523360248201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063e8ae2b6990604401602060405180830381865afa1580156109e6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a0a91906110ce565b610a485760405162461bcd60e51b815260206004820152600f60248201526e37b7363c903bb4ba34323930bbb2b960891b6044820152606401610320565b6000806000610a55610c94565b925092509250610a688582868686610d6a565b5050505050565b60405163e8ae2b6960e01b81527f63e58c34d94475ba3fc063e19800b940485850d84d09cd3c1f2c14192c559a6860048201523360248201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063e8ae2b6990604401602060405180830381865afa158015610af9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b1d91906110ce565b610b695760405162461bcd60e51b815260206004820152601260248201527f6f6e6c792061646d696e6973747261746f7200000000000000000000000000006044820152606401610320565b600054600160b01b900460ff16610bc25760405162461bcd60e51b815260206004820152600c60248201527f6e6f742070726f706f73656400000000000000000000000000000000000000006044820152606401610320565b60005461ffff828116600160b81b9092041614610c215760405162461bcd60e51b815260206004820152600f60248201527f696e76616c6964206e65772066656500000000000000000000000000000000006044820152606401610320565b600080547fffffffffffffff0000000000ffffffffffffffffffffffffffffffffffffffff16600160a01b61ffff841690810262ffffff60b01b1916919091179091556040519081527fda1e1a9a6410acc0398b3b64e0c0110b8df57e29bfe69a419cdd9ae12718c307906020016103a1565b60005460015461ffff600160a01b830416916001600160a01b0391821691168215610d0f576001600160a01b038216610d0f5760405162461bcd60e51b815260206004820152601c60248201527f696e76616c696420616c676562726120666565207265636569766572000000006044820152606401610320565b6001600160a01b038116610d655760405162461bcd60e51b815260206004820152601060248201527f696e76616c6964207265636569766572000000000000000000000000000000006044820152606401610320565b909192565b8261ffff831615610df0576000610d888261ffff86166103e8610e50565b9050610d948183611106565b9150610da1878483610ed1565b826001600160a01b0316876001600160a01b03167fb7ee7fc9dacb957cfa93faeb8ca1826292de295e18e287a347dddfde7ab48b4083604051610de691815260200190565b60405180910390a3505b610dfb868683610ed1565b846001600160a01b0316866001600160a01b03167f7a629b77ef27ad337abe438773206187960a90abfb43607826bef77d650e84b983604051610e4091815260200190565b60405180910390a3505050505050565b6000831580610e7157505082820282848281610e6e57610e6e61112d565b04145b15610e925760008211610e8357600080fd5b81810490829006151501610eca565b610e9d848484610f3b565b905060008280610eaf57610eaf61112d565b8486091115610eca576000198110610ec657600080fd5b6001015b9392505050565b600060405163a9059cbb60e01b6000526001600160a01b03841660045282602452602060006044600080895af19150813d1560203d146001600051141617169150806040525080610f3557604051637232c81f60e11b815260040160405180910390fd5b50505050565b60008383028160001985870982811083820303915050808411610f5d57600080fd5b80600003610f7057508290049050610eca565b8385870960008581038616958690049560026003880281188089028203028089028203028089028203028089028203028089028203028089029091030291819003819004600101858411909403939093029190930391909104170290509392505050565b80356001600160a01b0381168114610feb57600080fd5b919050565b60006020828403121561100257600080fd5b610eca82610fd4565b60006020828403121561101d57600080fd5b813561ffff81168114610eca57600080fd5b6000806020838503121561104257600080fd5b823567ffffffffffffffff8082111561105a57600080fd5b818501915085601f83011261106e57600080fd5b81358181111561107d57600080fd5b8660208260061b850101111561109257600080fd5b60209290920196919550909350505050565b600080604083850312156110b757600080fd5b6110c083610fd4565b946020939093013593505050565b6000602082840312156110e057600080fd5b81518015158114610eca57600080fd5b634e487b7160e01b600052603260045260246000fd5b8181038181111561112757634e487b7160e01b600052601160045260246000fd5b92915050565b634e487b7160e01b600052601260045260246000fdfea164736f6c6343000814000a000000000000000000000000b860200bd68dc39ceafd6ebb82883f189f4cda760000000000000000000000002e7bcddcd74ade69b67e816cb32db6f0b709cab5
Deployed Bytecode
0x608060405234801561001057600080fd5b506004361061011b5760003560e01c8063ad6129ac116100b2578063d17bc78311610081578063dfadc79411610066578063dfadc79414610291578063f3fef3a3146102a4578063ff3c43e1146102b757600080fd5b8063d17bc78314610276578063d9fb43531461027e57600080fd5b8063ad6129ac14610210578063b5f680ae14610218578063bbac3b8d1461022b578063c53b3fbe1461025257600080fd5b806350eea0c8116100ee57806350eea0c8146101ad57806362744405146101c05780639d754dde146101e85780639f856b8d146101fb57600080fd5b80631de4161314610120578063371abc951461015a5780634738761c1461018557806348a50fcf14610198575b600080fd5b6101477fb77a63f119f4dc2174dc6c76fc1a1565fa4f2b0dde50ed5c0465471cd9b331f681565b6040519081526020015b60405180910390f35b60005461016d906001600160a01b031681565b6040516001600160a01b039091168152602001610151565b60015461016d906001600160a01b031681565b6101ab6101a6366004610ff0565b6102ca565b005b6101ab6101bb366004610ff0565b6103ac565b6000546101d590600160b81b900461ffff1681565b60405161ffff9091168152602001610151565b60025461016d906001600160a01b031681565b6000546101d590600160a01b900461ffff1681565b6101ab610454565b6101ab610226366004610ff0565b6104bf565b6101477f63e58c34d94475ba3fc063e19800b940485850d84d09cd3c1f2c14192c559a6881565b60005461026690600160b01b900460ff1681565b6040519015158152602001610151565b6101ab610635565b6101ab61028c36600461100b565b6106c7565b6101ab61029f36600461102f565b6107ca565b6101ab6102b23660046110a4565b610948565b6101ab6102c536600461100b565b610a6f565b6002546001600160a01b031633146103295760405162461bcd60e51b815260206004820152601860248201527f6f6e6c7920616c676562726120666565206d616e61676572000000000000000060448201526064015b60405180910390fd5b6001600160a01b03811661033c57600080fd5b6001546001600160a01b039081169082160361035757600080fd5b600180546001600160a01b0319166001600160a01b0383169081179091556040519081527f34d1b5ef1c1c2c03a5000b91bef5c465790244c6751c794e5b45bed7657c38fd906020015b60405180910390a150565b6002546001600160a01b031633146104065760405162461bcd60e51b815260206004820152601860248201527f6f6e6c7920616c676562726120666565206d616e6167657200000000000000006044820152606401610320565b600380546001600160a01b0319166001600160a01b0383169081179091556040519081527fab6918ba7303f2f81e46e324b5f34af4bda562577c1da710e2034980fee1e82a906020016103a1565b6003546001600160a01b0316331461046b57600080fd5b60028054336001600160a01b031991821681179092556003805490911690556040519081527fecf97a11fb2f2bcc38d1b6881865ecc04405af2d8b953004c79b3ab398732d029060200160405180910390a1565b60405163e8ae2b6960e01b81527f63e58c34d94475ba3fc063e19800b940485850d84d09cd3c1f2c14192c559a6860048201523360248201527f000000000000000000000000b860200bd68dc39ceafd6ebb82883f189f4cda766001600160a01b03169063e8ae2b6990604401602060405180830381865afa158015610549573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061056d91906110ce565b6105b95760405162461bcd60e51b815260206004820152601260248201527f6f6e6c792061646d696e6973747261746f7200000000000000000000000000006044820152606401610320565b6001600160a01b0381166105cc57600080fd5b6000546001600160a01b03908116908216036105e757600080fd5b600080546001600160a01b0319166001600160a01b0383169081179091556040519081527f2f4db788b994a5908051d68a2340153f49870447185a244d2326861e60cc4186906020016103a1565b6002546001600160a01b0316331461068f5760405162461bcd60e51b815260206004820152601860248201527f6f6e6c7920616c676562726120666565206d616e6167657200000000000000006044820152606401610320565b6000805462ffffff60b01b191681556040517f9f4bbade0736edbd2ec12c598bdac4573af13a3b57820ae4c7da5c61703eaaff9190a1565b6002546001600160a01b031633146107215760405162461bcd60e51b815260206004820152601860248201527f6f6e6c7920616c676562726120666565206d616e6167657200000000000000006044820152606401610320565b6103e861ffff8216111561073457600080fd5b60005461ffff828116600160b81b9092041614801590610764575060005461ffff828116600160a01b9092041614155b61076d57600080fd5b6000805461ffff8316600160b81b0262ffffff60b01b1990911617600160b01b1790556040517f2d6ac59d6da98f80c7ea481d17c670ea310b000fff5cf1732d94d93652dd25b7906103a190839061ffff91909116815260200190565b6002546001600160a01b031633148061088c575060405163e8ae2b6960e01b81527fb77a63f119f4dc2174dc6c76fc1a1565fa4f2b0dde50ed5c0465471cd9b331f660048201523360248201527f000000000000000000000000b860200bd68dc39ceafd6ebb82883f189f4cda766001600160a01b03169063e8ae2b6990604401602060405180830381865afa158015610868573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061088c91906110ce565b6108ca5760405162461bcd60e51b815260206004820152600f60248201526e37b7363c903bb4ba34323930bbb2b960891b6044820152606401610320565b80600080806108d7610c94565b92509250925060005b8481101561093f576109378787838181106108fd576108fd6110f0565b6109139260206040909202019081019150610ff0565b83898985818110610926576109266110f0565b905060400201602001358787610d6a565b6001016108e0565b50505050505050565b6002546001600160a01b0316331480610a0a575060405163e8ae2b6960e01b81527fb77a63f119f4dc2174dc6c76fc1a1565fa4f2b0dde50ed5c0465471cd9b331f660048201523360248201527f000000000000000000000000b860200bd68dc39ceafd6ebb82883f189f4cda766001600160a01b03169063e8ae2b6990604401602060405180830381865afa1580156109e6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a0a91906110ce565b610a485760405162461bcd60e51b815260206004820152600f60248201526e37b7363c903bb4ba34323930bbb2b960891b6044820152606401610320565b6000806000610a55610c94565b925092509250610a688582868686610d6a565b5050505050565b60405163e8ae2b6960e01b81527f63e58c34d94475ba3fc063e19800b940485850d84d09cd3c1f2c14192c559a6860048201523360248201527f000000000000000000000000b860200bd68dc39ceafd6ebb82883f189f4cda766001600160a01b03169063e8ae2b6990604401602060405180830381865afa158015610af9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b1d91906110ce565b610b695760405162461bcd60e51b815260206004820152601260248201527f6f6e6c792061646d696e6973747261746f7200000000000000000000000000006044820152606401610320565b600054600160b01b900460ff16610bc25760405162461bcd60e51b815260206004820152600c60248201527f6e6f742070726f706f73656400000000000000000000000000000000000000006044820152606401610320565b60005461ffff828116600160b81b9092041614610c215760405162461bcd60e51b815260206004820152600f60248201527f696e76616c6964206e65772066656500000000000000000000000000000000006044820152606401610320565b600080547fffffffffffffff0000000000ffffffffffffffffffffffffffffffffffffffff16600160a01b61ffff841690810262ffffff60b01b1916919091179091556040519081527fda1e1a9a6410acc0398b3b64e0c0110b8df57e29bfe69a419cdd9ae12718c307906020016103a1565b60005460015461ffff600160a01b830416916001600160a01b0391821691168215610d0f576001600160a01b038216610d0f5760405162461bcd60e51b815260206004820152601c60248201527f696e76616c696420616c676562726120666565207265636569766572000000006044820152606401610320565b6001600160a01b038116610d655760405162461bcd60e51b815260206004820152601060248201527f696e76616c6964207265636569766572000000000000000000000000000000006044820152606401610320565b909192565b8261ffff831615610df0576000610d888261ffff86166103e8610e50565b9050610d948183611106565b9150610da1878483610ed1565b826001600160a01b0316876001600160a01b03167fb7ee7fc9dacb957cfa93faeb8ca1826292de295e18e287a347dddfde7ab48b4083604051610de691815260200190565b60405180910390a3505b610dfb868683610ed1565b846001600160a01b0316866001600160a01b03167f7a629b77ef27ad337abe438773206187960a90abfb43607826bef77d650e84b983604051610e4091815260200190565b60405180910390a3505050505050565b6000831580610e7157505082820282848281610e6e57610e6e61112d565b04145b15610e925760008211610e8357600080fd5b81810490829006151501610eca565b610e9d848484610f3b565b905060008280610eaf57610eaf61112d565b8486091115610eca576000198110610ec657600080fd5b6001015b9392505050565b600060405163a9059cbb60e01b6000526001600160a01b03841660045282602452602060006044600080895af19150813d1560203d146001600051141617169150806040525080610f3557604051637232c81f60e11b815260040160405180910390fd5b50505050565b60008383028160001985870982811083820303915050808411610f5d57600080fd5b80600003610f7057508290049050610eca565b8385870960008581038616958690049560026003880281188089028203028089028203028089028203028089028203028089028203028089029091030291819003819004600101858411909403939093029190930391909104170290509392505050565b80356001600160a01b0381168114610feb57600080fd5b919050565b60006020828403121561100257600080fd5b610eca82610fd4565b60006020828403121561101d57600080fd5b813561ffff81168114610eca57600080fd5b6000806020838503121561104257600080fd5b823567ffffffffffffffff8082111561105a57600080fd5b818501915085601f83011261106e57600080fd5b81358181111561107d57600080fd5b8660208260061b850101111561109257600080fd5b60209290920196919550909350505050565b600080604083850312156110b757600080fd5b6110c083610fd4565b946020939093013593505050565b6000602082840312156110e057600080fd5b81518015158114610eca57600080fd5b634e487b7160e01b600052603260045260246000fd5b8181038181111561112757634e487b7160e01b600052601160045260246000fd5b92915050565b634e487b7160e01b600052601260045260246000fdfea164736f6c6343000814000a
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000b860200bd68dc39ceafd6ebb82883f189f4cda760000000000000000000000002e7bcddcd74ade69b67e816cb32db6f0b709cab5
-----Decoded View---------------
Arg [0] : _factory (address): 0xb860200BD68dc39cEAfd6ebb82883f189f4CdA76
Arg [1] : _algebraFeeManager (address): 0x2e7BcddCD74aDE69B67E816cB32dB6F0B709Cab5
-----Encoded View---------------
2 Constructor Arguments found :
Arg [0] : 000000000000000000000000b860200bd68dc39ceafd6ebb82883f189f4cda76
Arg [1] : 0000000000000000000000002e7bcddcd74ade69b67e816cb32db6f0b709cab5
Loading...
Loading
Loading...
Loading
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.