编译器
0.8.10+commit.fc410830
文件 1 的 9:IERC20.sol
pragma solidity ^0.8.0;
interface IERC20 {
function totalSupply() external view returns (uint256);
function balanceOf(address account) external view returns (uint256);
function transfer(address recipient, uint256 amount) external returns (bool);
function allowance(address owner, address spender) external view returns (uint256);
function approve(address spender, uint256 amount) external returns (bool);
function transferFrom(
address sender,
address recipient,
uint256 amount
) external returns (bool);
event Transfer(address indexed from, address indexed to, uint256 value);
event Approval(address indexed owner, address indexed spender, uint256 value);
}
文件 2 的 9:IGaugeController.sol
pragma solidity 0.8.10;
interface IGaugeController {
function gauge_types(address _addr)external view returns(uint256);
function get_voting_escrow()external view returns(address);
function checkpoint_gauge(address addr)external;
function gauge_relative_weight(address addr, uint256 time)external view returns(uint256);
}
文件 3 的 9:IInsureToken.sol
pragma solidity 0.8.10;
interface IInsureToken {
function mint(address _to, uint256 _value)external returns(bool);
function emergency_mint(uint256 _amountOut, address _to)external;
function approve(address _spender, uint256 _value)external;
function rate()external view returns(uint256);
function future_epoch_time_write() external returns(uint256);
}
文件 4 的 9:IMinter.sol
pragma solidity 0.8.10;
import "./IGaugeController.sol";
interface IMinter {
function insure_token()external view returns(address);
function controller()external view returns(address);
function minted(address user, address gauge) external view returns(uint256);
function gauge_controller()external view returns(address);
}
文件 5 的 9:IOwnership.sol
pragma solidity 0.8.10;
interface IOwnership {
function owner() external view returns (address);
function futureOwner() external view returns (address);
function commitTransferOwnership(address newOwner) external;
function acceptTransferOwnership() external;
}
文件 6 的 9:IVotingEscrow.sol
pragma solidity 0.8.10;
interface IVotingEscrow {
function get_last_user_slope(address _addr) external view returns (uint256);
function locked__end(address _addr) external view returns (uint256);
function balanceOf(address _addr, uint256 _t)
external
view
returns (uint256);
function totalSupply(uint256 _t) external view returns (uint256);
function get_user_point_epoch(address _user)
external
view
returns (uint256);
function user_point_history__ts(address _addr, uint256 _idx)
external
view
returns (uint256);
}
文件 7 的 9:LiquidityGauge.sol
pragma solidity 0.8.10;
import "./interfaces/dao/IGaugeController.sol";
import "./interfaces/dao/IInsureToken.sol";
import "./interfaces/dao/IMinter.sol";
import "./interfaces/dao/IVotingEscrow.sol";
import "./interfaces/pool/IOwnership.sol";
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "@openzeppelin/contracts/utils/math/Math.sol";
import "@openzeppelin/contracts/security/ReentrancyGuard.sol";
contract LiquidityGauge is ReentrancyGuard {
event Deposit(address indexed provider, uint256 value);
event Withdraw(address indexed provider, uint256 value);
event UpdateLiquidityLimit(
address user,
uint256 original_balance,
uint256 original_supply,
uint256 working_balance,
uint256 working_supply,
uint256 voting_balance,
uint256 voting_total
);
uint256 constant TOKENLESS_PRODUCTION = 40;
uint256 constant BOOST_WARMUP = 86400 * 14;
uint256 constant WEEK = 604800;
IMinter public minter;
IInsureToken public insure_token;
IERC20 public template;
IGaugeController public controller;
IVotingEscrow public voting_escrow;
mapping(address => uint256) public balanceOf;
uint256 public totalSupply;
uint256 public future_epoch_time;
mapping(address => mapping(address => bool)) public approved_to_deposit;
mapping(address => uint256) public working_balances;
uint256 public working_supply;
uint256 public period;
uint256[100000000000000000000000000000] public period_timestamp;
uint256[100000000000000000000000000000] public integrate_inv_supply;
mapping(address => uint256) public integrate_inv_supply_of;
mapping(address => uint256) public integrate_checkpoint_of;
mapping(address => uint256) public integrate_fraction;
uint256 public inflation_rate;
bool public is_killed;
IOwnership public immutable ownership;
modifier onlyOwner() {
require(
ownership.owner() == msg.sender,
"Caller is not allowed to operate"
);
_;
}
constructor(
address _lp_addr,
address _minter,
address _ownership
) {
require(_lp_addr != address(0));
require(_minter != address(0));
template = IERC20(_lp_addr);
minter = IMinter(_minter);
address _insure_addr = minter.insure_token();
insure_token = IInsureToken(_insure_addr);
controller = IGaugeController(minter.gauge_controller());
voting_escrow = IVotingEscrow(controller.get_voting_escrow());
period_timestamp[0] = block.timestamp;
inflation_rate = insure_token.rate();
future_epoch_time = insure_token.future_epoch_time_write();
ownership = IOwnership(_ownership);
}
function _update_liquidity_limit(
address _addr,
uint256 _l,
uint256 _L
) internal {
uint256 _voting_balance = voting_escrow.balanceOf(
_addr,
block.timestamp
);
uint256 _voting_total = voting_escrow.totalSupply(block.timestamp);
uint256 _lim = (_l * TOKENLESS_PRODUCTION) / 100;
if (
(_voting_total > 0) &&
(block.timestamp > period_timestamp[0] + BOOST_WARMUP)
) {
_lim +=
(_L * _voting_balance * (100 - TOKENLESS_PRODUCTION)) /
_voting_total /
100;
}
_lim = min(_l, _lim);
uint256 _old_bal = working_balances[_addr];
working_balances[_addr] = _lim;
uint256 _working_supply = working_supply + _lim - _old_bal;
working_supply = _working_supply;
emit UpdateLiquidityLimit(
_addr,
_l,
_L,
_lim,
_working_supply,
_voting_balance,
_voting_total
);
}
struct CheckPointParameters {
uint256 period;
uint256 period_time;
uint256 integrate_inv_supply;
uint256 rate;
uint256 new_rate;
uint256 prev_future_epoch;
uint256 working_balance;
uint256 working_supply;
}
function _checkpoint(address _addr) internal {
CheckPointParameters memory _st;
_st.period = period;
_st.period_time = period_timestamp[_st.period];
_st.integrate_inv_supply = integrate_inv_supply[_st.period];
_st.rate = inflation_rate;
_st.new_rate = _st.rate;
_st.prev_future_epoch = future_epoch_time;
if (_st.prev_future_epoch >= _st.period_time) {
future_epoch_time = insure_token.future_epoch_time_write();
_st.new_rate = insure_token.rate();
inflation_rate = _st.new_rate;
}
controller.checkpoint_gauge(address(this));
uint256 _working_balance = working_balances[_addr];
uint256 _working_supply = working_supply;
if (is_killed) {
_st.rate = 0;
}
if (block.timestamp > _st.period_time) {
uint256 _prev_week_time = _st.period_time;
uint256 _week_time;
unchecked {
_week_time = min(
((_st.period_time + WEEK) / WEEK) * WEEK,
block.timestamp
);
}
for (uint256 i; i < 500;) {
uint256 _dt = _week_time - _prev_week_time;
uint256 _w = controller.gauge_relative_weight(
address(this),
(_prev_week_time / WEEK) * WEEK
);
if (_working_supply > 0) {
if (
_st.prev_future_epoch >= _prev_week_time &&
_st.prev_future_epoch < _week_time
) {
_st.integrate_inv_supply +=
(_st.rate *
_w *
(_st.prev_future_epoch - _prev_week_time)) /
_working_supply;
_st.rate = _st.new_rate;
_st.integrate_inv_supply +=
(_st.rate *
_w *
(_week_time - _st.prev_future_epoch)) /
_working_supply;
} else {
_st.integrate_inv_supply +=
(_st.rate * _w * _dt) /
_working_supply;
}
}
if (_week_time == block.timestamp) {
break;
}
_prev_week_time = _week_time;
_week_time = min(_week_time + WEEK, block.timestamp);
unchecked {
++i;
}
}
}
_st.period += 1;
period = _st.period;
period_timestamp[_st.period] = block.timestamp;
integrate_inv_supply[_st.period] = _st.integrate_inv_supply;
integrate_fraction[_addr] +=
(_working_balance *
(_st.integrate_inv_supply - integrate_inv_supply_of[_addr])) /
10 ** 18;
integrate_inv_supply_of[_addr] = _st.integrate_inv_supply;
integrate_checkpoint_of[_addr] = block.timestamp;
}
function user_checkpoint(address _addr) external returns(bool) {
require(
(msg.sender == _addr) || (msg.sender == address(minter)),
"dev: unauthorized"
);
_checkpoint(_addr);
_update_liquidity_limit(_addr, balanceOf[_addr], totalSupply);
return true;
}
function claimable_tokens(address _addr) external returns(uint256) {
_checkpoint(_addr);
return (integrate_fraction[_addr] -
minter.minted(_addr, address(this)));
}
function kick(address _addr) external {
uint256 _t_last = integrate_checkpoint_of[_addr];
uint256 _t_ve = voting_escrow.user_point_history__ts(
_addr,
voting_escrow.get_user_point_epoch(_addr)
);
uint256 _balance = balanceOf[_addr];
require(
voting_escrow.balanceOf(_addr, block.timestamp) == 0 ||
_t_ve > _t_last,
"dev: kick not allowed"
);
require(
working_balances[_addr] > (_balance * TOKENLESS_PRODUCTION) / 100,
"dev: kick not needed"
);
_checkpoint(_addr);
_update_liquidity_limit(_addr, balanceOf[_addr], totalSupply);
}
function set_approve_deposit(address _addr, bool can_deposit) external {
approved_to_deposit[_addr][msg.sender] = can_deposit;
}
function deposit(uint256 _value, address _addr) external nonReentrant {
if (_addr != msg.sender) {
require(approved_to_deposit[msg.sender][_addr], "Not approved");
}
_checkpoint(_addr);
if (_value != 0) {
uint256 _balance = balanceOf[_addr] + _value;
uint256 _supply = totalSupply + _value;
balanceOf[_addr] = _balance;
totalSupply = _supply;
_update_liquidity_limit(_addr, _balance, _supply);
require(template.transferFrom(msg.sender, address(this), _value));
}
emit Deposit(_addr, _value);
}
function withdraw(uint256 _value) external nonReentrant {
_checkpoint(msg.sender);
uint256 _balance = balanceOf[msg.sender] - _value;
uint256 _supply = totalSupply - _value;
balanceOf[msg.sender] = _balance;
totalSupply = _supply;
_update_liquidity_limit(msg.sender, _balance, _supply);
require(template.transfer(msg.sender, _value));
emit Withdraw(msg.sender, _value);
}
function integrate_checkpoint() external view returns(uint256) {
return period_timestamp[period];
}
function kill_me() external onlyOwner {
is_killed = !is_killed;
}
function min(uint256 a, uint256 b) internal pure returns(uint256) {
return a < b ? a : b;
}
}
文件 8 的 9:Math.sol
pragma solidity ^0.8.0;
library Math {
function max(uint256 a, uint256 b) internal pure returns (uint256) {
return a >= b ? a : b;
}
function min(uint256 a, uint256 b) internal pure returns (uint256) {
return a < b ? a : b;
}
function average(uint256 a, uint256 b) internal pure returns (uint256) {
return (a & b) + (a ^ b) / 2;
}
function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {
return a / b + (a % b == 0 ? 0 : 1);
}
}
文件 9 的 9:ReentrancyGuard.sol
pragma solidity ^0.8.0;
abstract contract ReentrancyGuard {
uint256 private constant _NOT_ENTERED = 1;
uint256 private constant _ENTERED = 2;
uint256 private _status;
constructor() {
_status = _NOT_ENTERED;
}
modifier nonReentrant() {
require(_status != _ENTERED, "ReentrancyGuard: reentrant call");
_status = _ENTERED;
_;
_status = _NOT_ENTERED;
}
}
{
"compilationTarget": {
"contracts/LiquidityGauge.sol": "LiquidityGauge"
},
"evmVersion": "london",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs"
},
"optimizer": {
"enabled": true,
"runs": 200000
},
"remappings": []
}
[{"inputs":[{"internalType":"address","name":"_lp_addr","type":"address"},{"internalType":"address","name":"_minter","type":"address"},{"internalType":"address","name":"_ownership","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"provider","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Deposit","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"original_balance","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"original_supply","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"working_balance","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"working_supply","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"voting_balance","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"voting_total","type":"uint256"}],"name":"UpdateLiquidityLimit","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"provider","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Withdraw","type":"event"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"approved_to_deposit","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_addr","type":"address"}],"name":"claimable_tokens","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"controller","outputs":[{"internalType":"contract IGaugeController","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_value","type":"uint256"},{"internalType":"address","name":"_addr","type":"address"}],"name":"deposit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"future_epoch_time","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"inflation_rate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"insure_token","outputs":[{"internalType":"contract IInsureToken","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"integrate_checkpoint","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"integrate_checkpoint_of","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"integrate_fraction","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"integrate_inv_supply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"integrate_inv_supply_of","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"is_killed","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_addr","type":"address"}],"name":"kick","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"kill_me","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"minter","outputs":[{"internalType":"contract IMinter","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ownership","outputs":[{"internalType":"contract IOwnership","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"period","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"period_timestamp","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_addr","type":"address"},{"internalType":"bool","name":"can_deposit","type":"bool"}],"name":"set_approve_deposit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"template","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_addr","type":"address"}],"name":"user_checkpoint","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"voting_escrow","outputs":[{"internalType":"contract IVotingEscrow","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_value","type":"uint256"}],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"working_balances","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"working_supply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"}]