Transactions
Token Transfers
Internal Transactions
Coin Balance History
Logs
Code
Read Contract
Write Contract
Warning! Contract bytecode has been changed and doesn't match the verified one. Therefore, interaction with this smart contract may be risky.
This contract has been verified via Sourcify.
View contract in Sourcify repository
- Contract name:
- LiquidityGaugeFactory
- Optimization enabled
- true
- Compiler version
- v0.7.1+commit.f4a555be
- Optimization runs
- 9999
- EVM Version
- istanbul
- Verified at
- 2023-06-11T14:09:59.138612Z
Constructor Arguments
00000000000000000000000062a0a61e3b9f6bcd9fb3936dde3e528ab5a04887
Arg [0] (address) : 0x62a0a61e3b9f6bcd9fb3936dde3e528ab5a04887
contracts/gauges/ethereum/LiquidityGaugeFactory.sol
// SPDX-License-Identifier: GPL-3.0-or-later
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
pragma solidity ^0.7.0;
pragma experimental ABIEncoderV2;
import "@balancer-labs/v2-interfaces/contracts/liquidity-mining/IBaseGaugeFactory.sol";
import "@balancer-labs/v2-interfaces/contracts/liquidity-mining/IStakingLiquidityGauge.sol";
import "@balancer-labs/v2-solidity-utils/contracts/openzeppelin/Clones.sol";
import "../BaseGaugeFactory.sol";
contract LiquidityGaugeFactory is BaseGaugeFactory {
constructor(IStakingLiquidityGauge gauge) BaseGaugeFactory(gauge) {
// solhint-disable-previous-line no-empty-blocks
}
/**
* @notice Deploys a new gauge for a Balancer pool.
* @dev As anyone can register arbitrary Balancer pools with the Vault,
* it's impossible to prove onchain that `pool` is a "valid" deployment.
*
* Care must be taken to ensure that gauges deployed from this factory are
* suitable before they are added to the GaugeController.
*
* It is possible to deploy multiple gauges for a single pool.
* @param pool The address of the pool for which to deploy a gauge
* @param relativeWeightCap The relative weight cap for the created gauge
* @return The address of the deployed gauge
*/
function create(address pool, uint256 relativeWeightCap) external override returns (address) {
address gauge = _create();
IStakingLiquidityGauge(gauge).initialize(pool, relativeWeightCap);
return gauge;
}
}
/IRewardTokenDistributor.sol
// SPDX-License-Identifier: GPL-3.0-or-later
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
pragma solidity ^0.7.0;
pragma experimental ABIEncoderV2;
import "../solidity-utils/openzeppelin/IERC20.sol";
// For compatibility, we're keeping the same function names as in the original Curve code, including the mixed-case
// naming convention.
// solhint-disable func-name-mixedcase, var-name-mixedcase
interface IRewardTokenDistributor {
struct Reward {
IERC20 token;
address distributor;
uint256 period_finish;
uint256 rate;
uint256 last_update;
uint256 integral;
}
function reward_tokens(uint256 index) external view returns (IERC20);
function reward_data(IERC20 token) external view returns (Reward memory);
function claim_rewards(address user) external;
function add_reward(IERC20 rewardToken, address distributor) external;
function set_reward_distributor(IERC20 rewardToken, address distributor) external;
function deposit_reward_token(IERC20 rewardToken, uint256 amount) external;
function claimable_reward(address rewardToken, address user) external view returns (uint256);
function claimable_reward_write(address rewardToken, address user) external returns (uint256);
}
/IStakingLiquidityGauge.sol
// SPDX-License-Identifier: GPL-3.0-or-later
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
pragma solidity ^0.7.0;
pragma experimental ABIEncoderV2;
import "../solidity-utils/openzeppelin/IERC20.sol";
import "./ILiquidityGauge.sol";
import "./IRewardTokenDistributor.sol";
// For compatibility, we're keeping the same function names as in the original Curve code, including the mixed-case
// naming convention.
// solhint-disable func-name-mixedcase, var-name-mixedcase
interface IStakingLiquidityGauge is IRewardTokenDistributor, ILiquidityGauge, IERC20 {
function initialize(address lpToken, uint256 relativeWeightCap) external;
function lp_token() external view returns (IERC20);
function deposit(uint256 value, address recipient) external;
function withdraw(uint256 value) external;
}
/ILiquidityGaugeFactory.sol
// SPDX-License-Identifier: GPL-3.0-or-later
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
pragma solidity ^0.7.0;
pragma experimental ABIEncoderV2;
import "./ILiquidityGauge.sol";
interface ILiquidityGaugeFactory {
/**
* @notice Returns true if `gauge` was created by this factory.
*/
function isGaugeFromFactory(address gauge) external view returns (bool);
}
/openzeppelin/IERC20.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.7.0;
/**
* @dev Interface of the ERC20 standard as defined in the EIP.
*/
interface IERC20 {
/**
* @dev Returns the amount of tokens in existence.
*/
function totalSupply() external view returns (uint256);
/**
* @dev Returns the amount of tokens owned by `account`.
*/
function balanceOf(address account) external view returns (uint256);
/**
* @dev Moves `amount` tokens from the caller's account to `recipient`.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transfer(address recipient, uint256 amount) external returns (bool);
/**
* @dev Returns the remaining number of tokens that `spender` will be
* allowed to spend on behalf of `owner` through {transferFrom}. This is
* zero by default.
*
* This value changes when {approve} or {transferFrom} are called.
*/
function allowance(address owner, address spender) external view returns (uint256);
/**
* @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* IMPORTANT: Beware that changing an allowance with this method brings the risk
* that someone may use both the old and the new allowance by unfortunate
* transaction ordering. One possible solution to mitigate this race
* condition is to first reduce the spender's allowance to 0 and set the
* desired value afterwards:
* https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
*
* Emits an {Approval} event.
*/
function approve(address spender, uint256 amount) external returns (bool);
/**
* @dev Moves `amount` tokens from `sender` to `recipient` using the
* allowance mechanism. `amount` is then deducted from the caller's
* allowance.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transferFrom(
address sender,
address recipient,
uint256 amount
) external returns (bool);
/**
* @dev Emitted when `value` tokens are moved from one account (`from`) to
* another (`to`).
*
* Note that `value` may be zero.
*/
event Transfer(address indexed from, address indexed to, uint256 value);
/**
* @dev Emitted when the allowance of a `spender` for an `owner` is set by
* a call to {approve}. `value` is the new allowance.
*/
event Approval(address indexed owner, address indexed spender, uint256 value);
}
/IBaseGaugeFactory.sol
// SPDX-License-Identifier: GPL-3.0-or-later
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
pragma solidity ^0.7.0;
import "./ILiquidityGaugeFactory.sol";
interface IBaseGaugeFactory is ILiquidityGaugeFactory {
/**
* @notice Deploys a new gauge for the given recipient, with an initial maximum relative weight cap.
* The recipient can either be a pool in mainnet, or a recipient in a child chain.
* @param recipient The address to receive BAL minted from the gauge
* @param relativeWeightCap The relative weight cap for the created gauge
* @return The address of the deployed gauge
*/
function create(address recipient, uint256 relativeWeightCap) external returns (address);
}
/ILiquidityGauge.sol
// SPDX-License-Identifier: GPL-3.0-or-later
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
pragma solidity ^0.7.0;
// For compatibility, we're keeping the same function names as in the original Curve code, including the mixed-case
// naming convention.
// solhint-disable func-name-mixedcase
// solhint-disable func-param-name-mixedcase
interface ILiquidityGauge {
// solhint-disable-next-line var-name-mixedcase
event RelativeWeightCapChanged(uint256 new_relative_weight_cap);
/**
* @notice Returns BAL liquidity emissions calculated during checkpoints for the given user.
* @param user User address.
* @return uint256 BAL amount to issue for the address.
*/
function integrate_fraction(address user) external view returns (uint256);
/**
* @notice Record a checkpoint for a given user.
* @param user User address.
* @return bool Always true.
*/
function user_checkpoint(address user) external returns (bool);
/**
* @notice Returns true if gauge is killed; false otherwise.
*/
function is_killed() external view returns (bool);
/**
* @notice Kills the gauge so it cannot mint BAL.
*/
function killGauge() external;
/**
* @notice Unkills the gauge so it can mint BAL again.
*/
function unkillGauge() external;
/**
* @notice Sets a new relative weight cap for the gauge.
* The value shall be normalized to 1e18, and not greater than MAX_RELATIVE_WEIGHT_CAP.
* @param relativeWeightCap New relative weight cap.
*/
function setRelativeWeightCap(uint256 relativeWeightCap) external;
/**
* @notice Gets the relative weight cap for the gauge.
*/
function getRelativeWeightCap() external view returns (uint256);
/**
* @notice Returns the gauge's relative weight for a given time, capped to its relative weight cap attribute.
* @param time Timestamp in the past or present.
*/
function getCappedRelativeWeight(uint256 time) external view returns (uint256);
}
/Clones.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (proxy/Clones.sol)
pragma solidity ^0.7.0;
/**
* @dev https://eips.ethereum.org/EIPS/eip-1167[EIP 1167] is a standard for
* deploying minimal proxy contracts, also known as "clones".
*
* > To simply and cheaply clone contract functionality in an immutable way, this standard specifies
* > a minimal bytecode implementation that delegates all calls to a known, fixed address.
*
* The library includes functions to deploy a proxy using either `create` (traditional deployment) or `create2`
* (salted deterministic deployment). It also includes functions to predict the addresses of clones deployed using the
* deterministic method.
*
* _Available since v3.4._
*/
library Clones {
// solhint-disable no-inline-assembly
/**
* @dev Deploys and returns the address of a clone that mimics the behaviour of `implementation`.
*
* This function uses the create opcode, which should never revert.
*/
function clone(address implementation) internal returns (address instance) {
assembly {
let ptr := mload(0x40)
mstore(ptr, 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000000000000000000000)
mstore(add(ptr, 0x14), shl(0x60, implementation))
mstore(add(ptr, 0x28), 0x5af43d82803e903d91602b57fd5bf30000000000000000000000000000000000)
instance := create(0, ptr, 0x37)
}
require(instance != address(0), "ERC1167: create failed");
}
/**
* @dev Deploys and returns the address of a clone that mimics the behaviour of `implementation`.
*
* This function uses the create2 opcode and a `salt` to deterministically deploy
* the clone. Using the same `implementation` and `salt` multiple time will revert, since
* the clones cannot be deployed twice at the same address.
*/
function cloneDeterministic(address implementation, bytes32 salt) internal returns (address instance) {
assembly {
let ptr := mload(0x40)
mstore(ptr, 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000000000000000000000)
mstore(add(ptr, 0x14), shl(0x60, implementation))
mstore(add(ptr, 0x28), 0x5af43d82803e903d91602b57fd5bf30000000000000000000000000000000000)
instance := create2(0, ptr, 0x37, salt)
}
require(instance != address(0), "ERC1167: create2 failed");
}
/**
* @dev Computes the address of a clone deployed using {Clones-cloneDeterministic}.
*/
function predictDeterministicAddress(
address implementation,
bytes32 salt,
address deployer
) internal pure returns (address predicted) {
assembly {
let ptr := mload(0x40)
mstore(ptr, 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000000000000000000000)
mstore(add(ptr, 0x14), shl(0x60, implementation))
mstore(add(ptr, 0x28), 0x5af43d82803e903d91602b57fd5bf3ff00000000000000000000000000000000)
mstore(add(ptr, 0x38), shl(0x60, deployer))
mstore(add(ptr, 0x4c), salt)
mstore(add(ptr, 0x6c), keccak256(ptr, 0x37))
predicted := keccak256(add(ptr, 0x37), 0x55)
}
}
/**
* @dev Computes the address of a clone deployed using {Clones-cloneDeterministic}.
*/
function predictDeterministicAddress(address implementation, bytes32 salt)
internal
view
returns (address predicted)
{
return predictDeterministicAddress(implementation, salt, address(this));
}
}
/
// SPDX-License-Identifier: GPL-3.0-or-later
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
pragma solidity ^0.7.0;
import "@balancer-labs/v2-interfaces/contracts/liquidity-mining/IBaseGaugeFactory.sol";
import "@balancer-labs/v2-interfaces/contracts/liquidity-mining/ILiquidityGauge.sol";
import "@balancer-labs/v2-solidity-utils/contracts/openzeppelin/Clones.sol";
abstract contract BaseGaugeFactory is IBaseGaugeFactory {
ILiquidityGauge private _gaugeImplementation;
mapping(address => bool) private _isGaugeFromFactory;
event GaugeCreated(address indexed gauge);
constructor(ILiquidityGauge gaugeImplementation) {
_gaugeImplementation = gaugeImplementation;
}
/**
* @notice Returns the address of the implementation used for gauge deployments.
*/
function getGaugeImplementation() public view returns (ILiquidityGauge) {
return _gaugeImplementation;
}
/**
* @notice Returns true if `gauge` was created by this factory.
*/
function isGaugeFromFactory(address gauge) external view override returns (bool) {
return _isGaugeFromFactory[gauge];
}
/**
* @dev Deploys a new gauge as a proxy of the implementation in storage.
* The deployed gauge must be initialized by the caller method.
* @return The address of the deployed gauge
*/
function _create() internal returns (address) {
address gauge = Clones.clone(address(_gaugeImplementation));
_isGaugeFromFactory[gauge] = true;
emit GaugeCreated(gauge);
return gauge;
}
}
Compiler Settings
{"remappings":[],"optimizer":{"runs":9999,"enabled":true},"metadata":{"bytecodeHash":"ipfs"},"libraries":{},"evmVersion":"istanbul","compilationTarget":{"contracts/gauges/ethereum/LiquidityGaugeFactory.sol":"LiquidityGaugeFactory"}}
Contract ABI
[{"type":"constructor","stateMutability":"nonpayable","inputs":[{"type":"address","name":"gauge","internalType":"contract IStakingLiquidityGauge"}]},{"type":"event","name":"GaugeCreated","inputs":[{"type":"address","name":"gauge","internalType":"address","indexed":true}],"anonymous":false},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"create","inputs":[{"type":"address","name":"pool","internalType":"address"},{"type":"uint256","name":"relativeWeightCap","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"contract ILiquidityGauge"}],"name":"getGaugeImplementation","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"isGaugeFromFactory","inputs":[{"type":"address","name":"gauge","internalType":"address"}]}]
Contract Creation Code
0x608060405234801561001057600080fd5b5060405161049c38038061049c83398101604081905261002f91610054565b600080546001600160a01b0319166001600160a01b0392909216919091179055610082565b600060208284031215610065578081fd5b81516001600160a01b038116811461007b578182fd5b9392505050565b61040b806100916000396000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c80630ecaea731461004657806339312dee1461006f578063ce3cc8bd14610077575b600080fd5b610059610054366004610322565b610097565b604051610066919061034c565b60405180910390f35b610059610135565b61008a610085366004610300565b610151565b6040516100669190610393565b6000806100a2610180565b6040517fcd6dc68700000000000000000000000000000000000000000000000000000000815290915073ffffffffffffffffffffffffffffffffffffffff82169063cd6dc687906100f9908790879060040161036d565b600060405180830381600087803b15801561011357600080fd5b505af1158015610127573d6000803e3d6000fd5b509293505050505b92915050565b60005473ffffffffffffffffffffffffffffffffffffffff1690565b73ffffffffffffffffffffffffffffffffffffffff811660009081526001602052604090205460ff165b919050565b6000805481906101a59073ffffffffffffffffffffffffffffffffffffffff16610226565b73ffffffffffffffffffffffffffffffffffffffff8116600081815260016020819052604080832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169092179091555192935090917faa98436d09d130af48de49867af8b723bbbebb0d737638b5fe8f1bf31bbb71c09190a2905090565b60006040517f3d602d80600a3d3981f3363d3d373d3d3d363d7300000000000000000000000081528260601b60148201527f5af43d82803e903d91602b57fd5bf3000000000000000000000000000000000060288201526037816000f091505073ffffffffffffffffffffffffffffffffffffffff811661017b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016102d39061039e565b60405180910390fd5b803573ffffffffffffffffffffffffffffffffffffffff8116811461012f57600080fd5b600060208284031215610311578081fd5b61031b83836102dc565b9392505050565b60008060408385031215610334578081fd5b61033e84846102dc565b946020939093013593505050565b73ffffffffffffffffffffffffffffffffffffffff91909116815260200190565b73ffffffffffffffffffffffffffffffffffffffff929092168252602082015260400190565b901515815260200190565b60208082526016908201527f455243313136373a20637265617465206661696c65640000000000000000000060408201526060019056fea26469706673582212209ffe9af57bfc53bc361c02d5fbc8fdfc432a2be95afb2fe86dc05ba2cbb2402a64736f6c6343000701003300000000000000000000000062a0a61e3b9f6bcd9fb3936dde3e528ab5a04887
Deployed ByteCode
0x608060405234801561001057600080fd5b50600436106100415760003560e01c80630ecaea731461004657806339312dee1461006f578063ce3cc8bd14610077575b600080fd5b610059610054366004610322565b610097565b604051610066919061034c565b60405180910390f35b610059610135565b61008a610085366004610300565b610151565b6040516100669190610393565b6000806100a2610180565b6040517fcd6dc68700000000000000000000000000000000000000000000000000000000815290915073ffffffffffffffffffffffffffffffffffffffff82169063cd6dc687906100f9908790879060040161036d565b600060405180830381600087803b15801561011357600080fd5b505af1158015610127573d6000803e3d6000fd5b509293505050505b92915050565b60005473ffffffffffffffffffffffffffffffffffffffff1690565b73ffffffffffffffffffffffffffffffffffffffff811660009081526001602052604090205460ff165b919050565b6000805481906101a59073ffffffffffffffffffffffffffffffffffffffff16610226565b73ffffffffffffffffffffffffffffffffffffffff8116600081815260016020819052604080832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169092179091555192935090917faa98436d09d130af48de49867af8b723bbbebb0d737638b5fe8f1bf31bbb71c09190a2905090565b60006040517f3d602d80600a3d3981f3363d3d373d3d3d363d7300000000000000000000000081528260601b60148201527f5af43d82803e903d91602b57fd5bf3000000000000000000000000000000000060288201526037816000f091505073ffffffffffffffffffffffffffffffffffffffff811661017b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016102d39061039e565b60405180910390fd5b803573ffffffffffffffffffffffffffffffffffffffff8116811461012f57600080fd5b600060208284031215610311578081fd5b61031b83836102dc565b9392505050565b60008060408385031215610334578081fd5b61033e84846102dc565b946020939093013593505050565b73ffffffffffffffffffffffffffffffffffffffff91909116815260200190565b73ffffffffffffffffffffffffffffffffffffffff929092168252602082015260400190565b901515815260200190565b60208082526016908201527f455243313136373a20637265617465206661696c65640000000000000000000060408201526060019056fea26469706673582212209ffe9af57bfc53bc361c02d5fbc8fdfc432a2be95afb2fe86dc05ba2cbb2402a64736f6c63430007010033