GLMR Price: $0.096214 (-0.61%)

Contract

0x158F484C82aADC378c511B8F46f5c89C67142452

Overview

GLMR Balance

Moonbeam Chain LogoMoonbeam Chain LogoMoonbeam Chain Logo0 GLMR

GLMR Value

$0.00

Token Holdings

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
Withdraw Tokens101639232025-03-25 3:19:429 hrs ago1742872782IN
0x158F484C...C67142452
0 GLMR0.021038531.25
Withdraw Tokens101497112025-03-24 3:19:2433 hrs ago1742786364IN
0x158F484C...C67142452
0 GLMR0.021038531.25
Withdraw Tokens101354762025-03-23 3:19:482 days ago1742699988IN
0x158F484C...C67142452
0 GLMR0.0210457131.26071973
Withdraw Tokens101212902025-03-22 3:20:063 days ago1742613606IN
0x158F484C...C67142452
0 GLMR0.021038531.25
Withdraw Tokens101070942025-03-21 3:20:244 days ago1742527224IN
0x158F484C...C67142452
0 GLMR0.021038531.25
Withdraw Tokens100928982025-03-20 3:19:365 days ago1742440776IN
0x158F484C...C67142452
0 GLMR0.021038531.25
Withdraw Tokens100787822025-03-19 3:17:426 days ago1742354262IN
0x158F484C...C67142452
0 GLMR0.021038531.25
Withdraw Tokens100647532025-03-18 3:17:067 days ago1742267826IN
0x158F484C...C67142452
0 GLMR0.021038531.25
Withdraw Tokens100506662025-03-17 3:17:188 days ago1742181438IN
0x158F484C...C67142452
0 GLMR0.021002531.25
Withdraw Tokens100366582025-03-16 3:18:549 days ago1742095134IN
0x158F484C...C67142452
0 GLMR0.021002531.25
Withdraw Tokens100225292025-03-15 3:18:0010 days ago1742008680IN
0x158F484C...C67142452
0 GLMR0.021002531.25
Withdraw Tokens100084102025-03-14 3:18:0611 days ago1741922286IN
0x158F484C...C67142452
0 GLMR0.021002531.25
Withdraw Tokens99941032025-03-13 2:51:3012 days ago1741834290IN
0x158F484C...C67142452
0 GLMR0.021002531.25

Latest 1 internal transaction

Parent Transaction Hash Block From To
95346802025-02-08 17:36:5444 days ago1739036214  Contract Creation0 GLMR
Loading...
Loading

Similar Match Source Code
This contract matches the deployed Bytecode of the Source Code for Contract 0x69de5cB1...66fFaA5ed
The constructor portion of the code might be different and could alter the actual behaviour of the contract

Contract Name:
AlgebraCommunityVault

Compiler Version
v0.8.20+commit.a1b79de6

Optimization Enabled:
Yes with 800 runs

Other Settings:
paris EvmVersion
File 1 of 9 : AlgebraCommunityVault.sol
// SPDX-License-Identifier: BUSL-1.1
pragma solidity =0.8.20;

import './libraries/SafeTransfer.sol';
import './libraries/FullMath.sol';

import './interfaces/vault/IAlgebraCommunityVault.sol';
import './interfaces/vault/IIncentiveManager.sol';
import './interfaces/vault/IAlgebraVaultFactory.sol';
import './libraries/TransferHelper.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.2
contract AlgebraCommunityVault is IAlgebraCommunityVault {
  
  address public immutable vaultFactory;
  address public immutable pool;

  modifier onlyWithdrawer() {
    require(
      msg.sender == IAlgebraVaultFactory(vaultFactory).algebraFeeManager() || 
      IAlgebraVaultFactory(vaultFactory).hasRole(IAlgebraVaultFactory(vaultFactory).COMMUNITY_FEE_WITHDRAWER_ROLE(), msg.sender), 
      'only withdrawer'
      );
    _;
  }


  constructor(address _vaultFactory, address _pool) {
    vaultFactory = _vaultFactory;
    pool = _pool;
  }

  /// @inheritdoc IAlgebraCommunityVault
  function withdraw(address token, uint256 amount) external override onlyWithdrawer {
    (uint16 _algebraFee, address _algebraFeeReceiver, address _communityFeeReceiver, uint16 _communityFee) = _readAndVerifyWithdrawSettings();
    _withdraw(token, _communityFeeReceiver, amount, _algebraFee, _algebraFeeReceiver, _communityFee);
  }

  /// @inheritdoc IAlgebraCommunityVault
  function withdrawTokens(WithdrawTokensParams[] calldata params) external override onlyWithdrawer {
    uint256 paramsLength = params.length;
    (uint16 _algebraFee, address _algebraFeeReceiver, address _communityFeeReceiver, uint16 _communityFee) = _readAndVerifyWithdrawSettings();

    unchecked {
      for (uint256 i; i < paramsLength; ++i) _withdraw(params[i].token, _communityFeeReceiver, params[i].amount, _algebraFee, _algebraFeeReceiver, _communityFee);
    }
  }

  function _readAndVerifyWithdrawSettings() private view returns (uint16 _algebraFee, address _algebraFeeReceiver, address _communityFeeReceiver, uint16 _communityFee) {
    (_algebraFee, _algebraFeeReceiver, _communityFeeReceiver) = (IAlgebraVaultFactory(vaultFactory).algebraFee(), IAlgebraVaultFactory(vaultFactory).algebraFeeReceiver(), IAlgebraVaultFactory(vaultFactory).communityFeeReceiver());
    _communityFee = IAlgebraVaultFactory(vaultFactory).communityFee();
    if (_communityFee != 0) require(_communityFeeReceiver != address(0), 'invalid community fee receiver');
    if (_algebraFee != 0) require(_algebraFeeReceiver != address(0), 'invalid algebra fee receiver');
  }

  function _withdraw(address token, address _communityFeeReceiver, uint256 amount, uint16 _algebraFee, address _algebraFeeReceiver, uint16 _communityFee) private {
    uint256 withdrawAmount = amount;

    if (_algebraFee != 0) {
      uint256 algebraFeeAmount = FullMath.mulDivRoundingUp(withdrawAmount, _algebraFee, IAlgebraVaultFactory(vaultFactory).ALGEBRA_FEE_DENOMINATOR());
      withdrawAmount -= algebraFeeAmount;
      SafeTransfer.safeTransfer(token, _algebraFeeReceiver, algebraFeeAmount);
      emit AlgebraTokensWithdrawal(token, _algebraFeeReceiver, algebraFeeAmount);
    }

    if (_communityFee != 0) {
      uint256 communityFeeAmount = FullMath.mulDivRoundingUp(withdrawAmount, _communityFee, IAlgebraVaultFactory(vaultFactory).ALGEBRA_FEE_DENOMINATOR());
      withdrawAmount -= communityFeeAmount;
      SafeTransfer.safeTransfer(token, _communityFeeReceiver, communityFeeAmount);
      emit CommunityTokensWithdrawal(token, _communityFeeReceiver, communityFeeAmount);
    }

    address feeDistributor = IAlgebraVaultFactory(vaultFactory).getFeeDistributorForPool(pool);
    if(feeDistributor != address(0) && withdrawAmount != 0) {
      TransferHelper.safeApprove(token, feeDistributor, withdrawAmount);
      IIncentiveManager(feeDistributor).notifyRewardAmount(token, withdrawAmount);
      TransferHelper.safeApprove(token, feeDistributor, 0);
      emit TokensWithdrawal(token, feeDistributor, withdrawAmount);
    } else {
      SafeTransfer.safeTransfer(token, _communityFeeReceiver, withdrawAmount);
      emit TokensWithdrawal(token, _communityFeeReceiver, withdrawAmount);
    }
  }
}

File 2 of 9 : IERC20.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol)

pragma solidity ^0.8.0;

/**
 * @dev Interface of the ERC20 standard as defined in the EIP.
 */
interface IERC20 {
    /**
     * @dev Emitted when `value` tokens are moved from one account (`from`) to
     * another (`to`).
     *
     * Note that `value` may be zero.
     */
    event Transfer(address indexed from, address indexed to, uint256 value);

    /**
     * @dev Emitted when the allowance of a `spender` for an `owner` is set by
     * a call to {approve}. `value` is the new allowance.
     */
    event Approval(address indexed owner, address indexed spender, uint256 value);

    /**
     * @dev Returns the amount of tokens in existence.
     */
    function totalSupply() external view returns (uint256);

    /**
     * @dev Returns the amount of tokens owned by `account`.
     */
    function balanceOf(address account) external view returns (uint256);

    /**
     * @dev Moves `amount` tokens from the caller's account to `to`.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transfer(address to, uint256 amount) external returns (bool);

    /**
     * @dev Returns the remaining number of tokens that `spender` will be
     * allowed to spend on behalf of `owner` through {transferFrom}. This is
     * zero by default.
     *
     * This value changes when {approve} or {transferFrom} are called.
     */
    function allowance(address owner, address spender) external view returns (uint256);

    /**
     * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * IMPORTANT: Beware that changing an allowance with this method brings the risk
     * that someone may use both the old and the new allowance by unfortunate
     * transaction ordering. One possible solution to mitigate this race
     * condition is to first reduce the spender's allowance to 0 and set the
     * desired value afterwards:
     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
     *
     * Emits an {Approval} event.
     */
    function approve(address spender, uint256 amount) external returns (bool);

    /**
     * @dev Moves `amount` tokens from `from` to `to` using the
     * allowance mechanism. `amount` is then deducted from the caller's
     * allowance.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transferFrom(address from, address to, uint256 amount) external returns (bool);
}

File 3 of 9 : IAlgebraPoolErrors.sol
// 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 plugin fee param greater than fee/override fee
  error incorrectPluginFee();

  /// @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();
}

File 4 of 9 : IAlgebraCommunityVault.sol
// 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 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 CommunityTokensWithdrawal(address indexed token, address indexed to, uint256 amount);

  

  /// @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;

  
}

File 5 of 9 : IAlgebraVaultFactory.sol
// 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 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);

  event VaultCreated(address pool, address vault);

  /// @notice returns address of the community fee vault for the pool
  /// @param pool the address of Algebra Integral pool
  /// @return communityFeeVault the address of community fee vault
  function getVaultForPool(address pool) external view returns (address communityFeeVault);

  /// @notice creates the community fee vault for the pool if needed
  /// @param pool the address of Algebra Integral pool
  /// @return communityFeeVault the address of community fee vault
  function createVaultForPool(
    address pool,
    address creator,
    address deployer,
    address token0,
    address token1
  ) external returns (address communityFeeVault);

  // ### 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;

  function algebraFeeManager() external view returns (address algebraFeeManager);
  function COMMUNITY_FEE_WITHDRAWER_ROLE() external view returns (bytes32);
  function hasRole(bytes32 role, address account) external view returns (bool);
  function algebraFee() external view returns (uint16);
  function algebraFeeReceiver() external view returns (address);
  function communityFeeReceiver() external view returns (address);
  function ALGEBRA_FEE_DENOMINATOR() external view returns (uint16);
  function communityFee() external view returns (uint16);
  function getFeeDistributorForPool(address poolAddress) external view returns (address);
}

File 6 of 9 : IIncentiveManager.sol
// SPDX-License-Identifier: GPL-2.0-or-later
pragma solidity >=0.5.0;

/// @title The interface for the StellaSwap Incentive Manager
/// @dev Version: StellaSwap
interface IIncentiveManager {
  function notifyRewardAmount(address token, uint256 amount) external;
}

File 7 of 9 : FullMath.sol
// 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))
    }
  }
}

File 8 of 9 : SafeTransfer.sol
// 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();
  }
}

File 9 of 9 : TransferHelper.sol
// SPDX-License-Identifier: GPL-2.0-or-later
pragma solidity >=0.6.0;

import '@openzeppelin/contracts/token/ERC20/IERC20.sol';

/// @dev Credit to Uniswap Labs under GPL-2.0-or-later license:
/// https://github.com/Uniswap/v3-periphery
library TransferHelper {
    /// @notice Transfers tokens from the targeted address to the given destination
    /// @notice Errors with 'STF' if transfer fails
    /// @param token The contract address of the token to be transferred
    /// @param from The originating address from which the tokens will be transferred
    /// @param to The destination address of the transfer
    /// @param value The amount to be transferred
    function safeTransferFrom(
        address token,
        address from,
        address to,
        uint256 value
    ) internal {
        (bool success, bytes memory data) = token.call(
            abi.encodeWithSelector(IERC20.transferFrom.selector, from, to, value)
        );
        require(success && (data.length == 0 || abi.decode(data, (bool))), 'STF');
    }

    /// @notice Transfers tokens from msg.sender to a recipient
    /// @dev Errors with ST if transfer fails
    /// @param token The contract address of the token which will be transferred
    /// @param to The recipient of the transfer
    /// @param value The value of the transfer
    function safeTransfer(
        address token,
        address to,
        uint256 value
    ) internal {
        (bool success, bytes memory data) = token.call(abi.encodeWithSelector(IERC20.transfer.selector, to, value));
        require(success && (data.length == 0 || abi.decode(data, (bool))), 'ST');
    }

    /// @notice Approves the stipulated contract to spend the given allowance in the given token
    /// @dev Errors with 'SA' if transfer fails
    /// @param token The contract address of the token to be approved
    /// @param to The target of the approval
    /// @param value The amount of the given token the target will be allowed to spend
    function safeApprove(
        address token,
        address to,
        uint256 value
    ) internal {
        (bool success, bytes memory data) = token.call(abi.encodeWithSelector(IERC20.approve.selector, to, value));
        require(success && (data.length == 0 || abi.decode(data, (bool))), 'SA');
    }

    /// @notice Transfers NativeToken to the recipient address
    /// @dev Fails with `STE`
    /// @param to The destination of the transfer
    /// @param value The value to be transferred
    function safeTransferNative(address to, uint256 value) internal {
        (bool success, ) = to.call{value: value}(new bytes(0));
        require(success, 'STE');
    }
}

Settings
{
  "evmVersion": "paris",
  "optimizer": {
    "enabled": true,
    "runs": 800
  },
  "metadata": {
    "bytecodeHash": "none"
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  },
  "libraries": {}
}

Contract Security Audit

Contract ABI

API
[{"inputs":[{"internalType":"address","name":"_vaultFactory","type":"address"},{"internalType":"address","name":"_pool","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"transferFailed","type":"error"},{"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":[{"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":"CommunityTokensWithdrawal","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":"pool","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"vaultFactory","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","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"}]

Deployed Bytecode

0x608060405234801561001057600080fd5b506004361061004c5760003560e01c806316f0115b14610051578063d8a06f7314610094578063dfadc794146100bb578063f3fef3a3146100d0575b600080fd5b6100787f000000000000000000000000413a49b41f689d6d1b9964748a6c8e1de5af126c81565b6040516001600160a01b03909116815260200160405180910390f35b6100787f0000000000000000000000009b81835b2f7b51447d5e4c07ae18f05dfe62715081565b6100ce6100c9366004610f02565b6100e3565b005b6100ce6100de366004610f8f565b610374565b7f0000000000000000000000009b81835b2f7b51447d5e4c07ae18f05dfe6271506001600160a01b0316639d754dde6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610141573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101659190610fbb565b6001600160a01b0316336001600160a01b031614806102ae57507f0000000000000000000000009b81835b2f7b51447d5e4c07ae18f05dfe6271506001600160a01b03166391d148547f0000000000000000000000009b81835b2f7b51447d5e4c07ae18f05dfe6271506001600160a01b0316631de416136040518163ffffffff1660e01b8152600401602060405180830381865afa15801561020c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102309190610fd8565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b1681526004810191909152336024820152604401602060405180830381865afa15801561028a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102ae9190610ff1565b6102f15760405162461bcd60e51b815260206004820152600f60248201526e37b7363c903bb4ba34323930bbb2b960891b60448201526064015b60405180910390fd5b8060008080806102ff6105a9565b935093509350935060005b8581101561036a5761036288888381811061032757610327611013565b61033d9260206040909202019081019150611029565b848a8a8581811061035057610350611013565b9050604002016020013588888761088b565b60010161030a565b5050505050505050565b7f0000000000000000000000009b81835b2f7b51447d5e4c07ae18f05dfe6271506001600160a01b0316639d754dde6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156103d2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103f69190610fbb565b6001600160a01b0316336001600160a01b0316148061053f57507f0000000000000000000000009b81835b2f7b51447d5e4c07ae18f05dfe6271506001600160a01b03166391d148547f0000000000000000000000009b81835b2f7b51447d5e4c07ae18f05dfe6271506001600160a01b0316631de416136040518163ffffffff1660e01b8152600401602060405180830381865afa15801561049d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104c19190610fd8565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b1681526004810191909152336024820152604401602060405180830381865afa15801561051b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061053f9190610ff1565b61057d5760405162461bcd60e51b815260206004820152600f60248201526e37b7363c903bb4ba34323930bbb2b960891b60448201526064016102e8565b60008060008061058b6105a9565b93509350935093506105a186838787878661088b565b505050505050565b6000806000807f0000000000000000000000009b81835b2f7b51447d5e4c07ae18f05dfe6271506001600160a01b0316639f856b8d6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561060d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106319190611046565b7f0000000000000000000000009b81835b2f7b51447d5e4c07ae18f05dfe6271506001600160a01b0316634738761c6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561068f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106b39190610fbb565b7f0000000000000000000000009b81835b2f7b51447d5e4c07ae18f05dfe6271506001600160a01b031663371abc956040518163ffffffff1660e01b8152600401602060405180830381865afa158015610711573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107359190610fbb565b8094508195508296505050507f0000000000000000000000009b81835b2f7b51447d5e4c07ae18f05dfe6271506001600160a01b0316638961be6b6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561079f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107c39190611046565b905061ffff811615610825576001600160a01b0382166108255760405162461bcd60e51b815260206004820152601e60248201527f696e76616c696420636f6d6d756e69747920666565207265636569766572000060448201526064016102e8565b61ffff841615610885576001600160a01b0383166108855760405162461bcd60e51b815260206004820152601c60248201527f696e76616c696420616c6765627261206665652072656365697665720000000060448201526064016102e8565b90919293565b8361ffff84161561099457600061092c828661ffff167f0000000000000000000000009b81835b2f7b51447d5e4c07ae18f05dfe6271506001600160a01b031663a760babe6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156108ff573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109239190611046565b61ffff16610c69565b9050610938818361106a565b9150610945888583610cea565b836001600160a01b0316886001600160a01b03167fb7ee7fc9dacb957cfa93faeb8ca1826292de295e18e287a347dddfde7ab48b408360405161098a91815260200190565b60405180910390a3505b61ffff821615610a6f576000610a07828461ffff167f0000000000000000000000009b81835b2f7b51447d5e4c07ae18f05dfe6271506001600160a01b031663a760babe6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156108ff573d6000803e3d6000fd5b9050610a13818361106a565b9150610a20888883610cea565b866001600160a01b0316886001600160a01b03167fdc6a871268e13da5cb4d864a1513222856d43b7cb3209dbe807d171a61cd80d683604051610a6591815260200190565b60405180910390a3505b604051638b07527f60e01b81526001600160a01b037f000000000000000000000000413a49b41f689d6d1b9964748a6c8e1de5af126c811660048301526000917f0000000000000000000000009b81835b2f7b51447d5e4c07ae18f05dfe62715090911690638b07527f90602401602060405180830381865afa158015610afa573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b1e9190610fbb565b90506001600160a01b03811615801590610b3757508115155b15610c0757610b47888284610d54565b60405163b66503cf60e01b81526001600160a01b0389811660048301526024820184905282169063b66503cf90604401600060405180830381600087803b158015610b9157600080fd5b505af1158015610ba5573d6000803e3d6000fd5b50505050610bb588826000610d54565b806001600160a01b0316886001600160a01b03167f7a629b77ef27ad337abe438773206187960a90abfb43607826bef77d650e84b984604051610bfa91815260200190565b60405180910390a361036a565b610c12888884610cea565b866001600160a01b0316886001600160a01b03167f7a629b77ef27ad337abe438773206187960a90abfb43607826bef77d650e84b984604051610c5791815260200190565b60405180910390a35050505050505050565b6000831580610c8a57505082820282848281610c8757610c87611091565b04145b15610cab5760008211610c9c57600080fd5b81810490829006151501610ce3565b610cb6848484610e69565b905060008280610cc857610cc8611091565b8486091115610ce3576000198110610cdf57600080fd5b6001015b9392505050565b600060405163a9059cbb60e01b6000526001600160a01b03841660045282602452602060006044600080895af19150813d1560203d146001600051141617169150806040525080610d4e57604051637232c81f60e11b815260040160405180910390fd5b50505050565b604080516001600160a01b038481166024830152604480830185905283518084039091018152606490920183526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1663095ea7b360e01b1790529151600092839290871691610dc591906110a7565b6000604051808303816000865af19150503d8060008114610e02576040519150601f19603f3d011682016040523d82523d6000602084013e610e07565b606091505b5091509150818015610e31575080511580610e31575080806020019051810190610e319190610ff1565b610e625760405162461bcd60e51b8152602060048201526002602482015261534160f01b60448201526064016102e8565b5050505050565b60008383028160001985870982811083820303915050808411610e8b57600080fd5b80600003610e9e57508290049050610ce3565b8385870960008581038616958690049560026003880281188089028203028089028203028089028203028089028203028089028203028089029091030291819003819004600101858411909403939093029190930391909104170290509392505050565b60008060208385031215610f1557600080fd5b823567ffffffffffffffff80821115610f2d57600080fd5b818501915085601f830112610f4157600080fd5b813581811115610f5057600080fd5b8660208260061b8501011115610f6557600080fd5b60209290920196919550909350505050565b6001600160a01b0381168114610f8c57600080fd5b50565b60008060408385031215610fa257600080fd5b8235610fad81610f77565b946020939093013593505050565b600060208284031215610fcd57600080fd5b8151610ce381610f77565b600060208284031215610fea57600080fd5b5051919050565b60006020828403121561100357600080fd5b81518015158114610ce357600080fd5b634e487b7160e01b600052603260045260246000fd5b60006020828403121561103b57600080fd5b8135610ce381610f77565b60006020828403121561105857600080fd5b815161ffff81168114610ce357600080fd5b8181038181111561108b57634e487b7160e01b600052601160045260246000fd5b92915050565b634e487b7160e01b600052601260045260246000fd5b6000825160005b818110156110c857602081860181015185830152016110ae565b50600092019182525091905056fea164736f6c6343000814000a

Block Transaction Gas Used Reward
view all blocks collator

Block Uncle Number Difficulty Gas Used Reward
View All Uncles
Loading...
Loading
Loading...
Loading
Loading...
Loading

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
Loading...
Loading
Loading...
Loading
[ Download: CSV Export  ]
[ Download: CSV Export  ]

A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.