Source Code
Latest 1 from a total of 1 transactions
| Transaction Hash |
|
Block
|
From
|
To
|
|||||
|---|---|---|---|---|---|---|---|---|---|
| Change Community... | 894249 | 400 days ago | IN | 0 S | 0.00005913 |
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Cross-Chain Transactions
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
Contract ABI
API[{"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
Loading...
Loading
Net Worth in USD
$1.80
Net Worth in S
Token Allocations
FRXUSD
64.69%
TAILS
29.74%
FRXETH
5.57%
Multichain Portfolio | 35 Chains
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.