编译器
0.8.11+commit.d7f03943
文件 1 的 6:Address.sol
pragma solidity ^0.8.0;
library Address {
function isContract(address account) internal view returns (bool) {
uint256 size;
assembly {
size := extcodesize(account)
}
return size > 0;
}
function sendValue(address payable recipient, uint256 amount) internal {
require(address(this).balance >= amount, "Address: insufficient balance");
(bool success, ) = recipient.call{value: amount}("");
require(success, "Address: unable to send value, recipient may have reverted");
}
function functionCall(address target, bytes memory data) internal returns (bytes memory) {
return functionCall(target, data, "Address: low-level call failed");
}
function functionCall(
address target,
bytes memory data,
string memory errorMessage
) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0, errorMessage);
}
function functionCallWithValue(
address target,
bytes memory data,
uint256 value
) internal returns (bytes memory) {
return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
}
function functionCallWithValue(
address target,
bytes memory data,
uint256 value,
string memory errorMessage
) internal returns (bytes memory) {
require(address(this).balance >= value, "Address: insufficient balance for call");
require(isContract(target), "Address: call to non-contract");
(bool success, bytes memory returndata) = target.call{value: value}(data);
return verifyCallResult(success, returndata, errorMessage);
}
function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
return functionStaticCall(target, data, "Address: low-level static call failed");
}
function functionStaticCall(
address target,
bytes memory data,
string memory errorMessage
) internal view returns (bytes memory) {
require(isContract(target), "Address: static call to non-contract");
(bool success, bytes memory returndata) = target.staticcall(data);
return verifyCallResult(success, returndata, errorMessage);
}
function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
return functionDelegateCall(target, data, "Address: low-level delegate call failed");
}
function functionDelegateCall(
address target,
bytes memory data,
string memory errorMessage
) internal returns (bytes memory) {
require(isContract(target), "Address: delegate call to non-contract");
(bool success, bytes memory returndata) = target.delegatecall(data);
return verifyCallResult(success, returndata, errorMessage);
}
function verifyCallResult(
bool success,
bytes memory returndata,
string memory errorMessage
) internal pure returns (bytes memory) {
if (success) {
return returndata;
} else {
if (returndata.length > 0) {
assembly {
let returndata_size := mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert(errorMessage);
}
}
}
}
文件 2 的 6:BalInvestor.sol
pragma solidity 0.8.11;
pragma abicoder v2;
import { IERC20 } from "@openzeppelin/contracts-0.8/token/ERC20/IERC20.sol";
import { SafeERC20 } from "@openzeppelin/contracts-0.8/token/ERC20/utils/SafeERC20.sol";
import { IVault, IPriceOracle, IAsset } from "./Interfaces.sol";
abstract contract BalInvestor {
using SafeERC20 for IERC20;
IVault public immutable BALANCER_VAULT;
address public immutable BAL;
address public immutable WETH;
address public immutable BALANCER_POOL_TOKEN;
bytes32 public immutable BAL_ETH_POOL_ID;
constructor(
IVault _balancerVault,
address _bal,
address _weth,
bytes32 _balETHPoolId
) {
(
address poolAddress,
) = _balancerVault.getPool(_balETHPoolId);
require(poolAddress != address(0), "!poolAddress");
BALANCER_VAULT = _balancerVault;
BAL = _bal;
WETH = _weth;
BALANCER_POOL_TOKEN = poolAddress;
BAL_ETH_POOL_ID = _balETHPoolId;
}
function _setApprovals() internal {
IERC20(WETH).safeApprove(address(BALANCER_VAULT), type(uint256).max);
IERC20(BAL).safeApprove(address(BALANCER_VAULT), type(uint256).max);
}
function _getBptPrice() internal view returns (uint256) {
IPriceOracle.OracleAverageQuery[] memory queries = new IPriceOracle.OracleAverageQuery[](1);
queries[0].variable = IPriceOracle.Variable.BPT_PRICE;
queries[0].secs = 3600;
queries[0].ago = 0;
return IPriceOracle(BALANCER_POOL_TOKEN).getTimeWeightedAverage(queries)[0];
}
function _getMinOut(uint256 amount, uint256 minOutBps) internal view returns (uint256) {
uint256 bptOraclePrice = _getBptPrice();
uint256 minOut = (((amount * 1e18) / bptOraclePrice) * minOutBps) / 10000;
return minOut;
}
function _investBalToPool(uint256 amount, uint256 minOut) internal {
IERC20(BAL).safeTransferFrom(msg.sender, address(this), amount);
IAsset[] memory assets = new IAsset[](2);
assets[0] = IAsset(BAL);
assets[1] = IAsset(WETH);
uint256[] memory maxAmountsIn = new uint256[](2);
maxAmountsIn[0] = amount;
maxAmountsIn[1] = 0;
BALANCER_VAULT.joinPool(
BAL_ETH_POOL_ID,
address(this),
address(this),
IVault.JoinPoolRequest(
assets,
maxAmountsIn,
abi.encode(IVault.JoinKind.EXACT_TOKENS_IN_FOR_BPT_OUT, maxAmountsIn, minOut),
false
)
);
}
}
文件 3 的 6:CrvDepositorWrapper.sol
pragma solidity 0.8.11;
import { IERC20 } from "@openzeppelin/contracts-0.8/token/ERC20/IERC20.sol";
import { IVault, ICrvDepositorWrapper } from "./Interfaces.sol";
import { BalInvestor } from "./BalInvestor.sol";
interface ICrvDepositor {
function depositFor(
address to,
uint256 _amount,
bool _lock,
address _stakeAddress
) external;
}
contract CrvDepositorWrapper is ICrvDepositorWrapper, BalInvestor {
address public immutable crvDeposit;
constructor(
address _crvDeposit,
IVault _balancerVault,
address _bal,
address _weth,
bytes32 _balETHPoolId
) BalInvestor(_balancerVault, _bal, _weth, _balETHPoolId) {
crvDeposit = _crvDeposit;
}
function setApprovals() external {
_setApprovals();
require(IERC20(BALANCER_POOL_TOKEN).approve(crvDeposit, type(uint256).max), "!approval");
}
function getMinOut(uint256 _amount, uint256 _outputBps) external view returns (uint256) {
return _getMinOut(_amount, _outputBps);
}
function deposit(
uint256 _amount,
uint256 _minOut,
bool _lock,
address _stakeAddress
) external {
_investBalToPool(_amount, _minOut);
uint256 bptBalance = IERC20(BALANCER_POOL_TOKEN).balanceOf(address(this));
ICrvDepositor(crvDeposit).depositFor(msg.sender, bptBalance, _lock, _stakeAddress);
}
}
文件 4 的 6: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);
}
文件 5 的 6:Interfaces.sol
pragma solidity 0.8.11;
interface IPriceOracle {
struct OracleAverageQuery {
Variable variable;
uint256 secs;
uint256 ago;
}
enum Variable {
PAIR_PRICE,
BPT_PRICE,
INVARIANT
}
function getTimeWeightedAverage(OracleAverageQuery[] memory queries)
external
view
returns (uint256[] memory results);
}
interface IVault {
enum PoolSpecialization {
GENERAL,
MINIMAL_SWAP_INFO,
TWO_TOKEN
}
enum JoinKind {
INIT,
EXACT_TOKENS_IN_FOR_BPT_OUT,
TOKEN_IN_FOR_EXACT_BPT_OUT,
ALL_TOKENS_IN_FOR_EXACT_BPT_OUT
}
enum SwapKind {
GIVEN_IN,
GIVEN_OUT
}
struct SingleSwap {
bytes32 poolId;
SwapKind kind;
IAsset assetIn;
IAsset assetOut;
uint256 amount;
bytes userData;
}
struct FundManagement {
address sender;
bool fromInternalBalance;
address payable recipient;
bool toInternalBalance;
}
struct JoinPoolRequest {
IAsset[] assets;
uint256[] maxAmountsIn;
bytes userData;
bool fromInternalBalance;
}
function getPool(bytes32 poolId) external view returns (address, PoolSpecialization);
function getPoolTokens(bytes32 poolId)
external
view
returns (
address[] memory tokens,
uint256[] memory balances,
uint256 lastChangeBlock
);
function joinPool(
bytes32 poolId,
address sender,
address recipient,
JoinPoolRequest memory request
) external payable;
function swap(
SingleSwap memory singleSwap,
FundManagement memory funds,
uint256 limit,
uint256 deadline
) external returns (uint256 amountCalculated);
function exitPool(
bytes32 poolId,
address sender,
address payable recipient,
ExitPoolRequest memory request
) external;
struct ExitPoolRequest {
IAsset[] assets;
uint256[] minAmountsOut;
bytes userData;
bool toInternalBalance;
}
enum ExitKind {
EXACT_BPT_IN_FOR_ONE_TOKEN_OUT,
EXACT_BPT_IN_FOR_TOKENS_OUT,
BPT_IN_FOR_EXACT_TOKENS_OUT,
MANAGEMENT_FEE_TOKENS_OUT
}
}
interface IAsset {
}
interface IAuraLocker {
function lock(address _account, uint256 _amount) external;
function checkpointEpoch() external;
function epochCount() external view returns (uint256);
function balanceAtEpochOf(uint256 _epoch, address _user) external view returns (uint256 amount);
function totalSupplyAtEpoch(uint256 _epoch) external view returns (uint256 supply);
function queueNewRewards(address _rewardsToken, uint256 reward) external;
function getReward(address _account, bool _stake) external;
function getReward(address _account) external;
}
interface IExtraRewardsDistributor {
function addReward(address _token, uint256 _amount) external;
}
interface ICrvDepositorWrapper {
function getMinOut(uint256, uint256) external view returns (uint256);
function deposit(
uint256,
uint256,
bool,
address _stakeAddress
) external;
}
文件 6 的 6:SafeERC20.sol
pragma solidity ^0.8.0;
import "../IERC20.sol";
import "../../../utils/Address.sol";
library SafeERC20 {
using Address for address;
function safeTransfer(
IERC20 token,
address to,
uint256 value
) internal {
_callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));
}
function safeTransferFrom(
IERC20 token,
address from,
address to,
uint256 value
) internal {
_callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));
}
function safeApprove(
IERC20 token,
address spender,
uint256 value
) internal {
require(
(value == 0) || (token.allowance(address(this), spender) == 0),
"SafeERC20: approve from non-zero to non-zero allowance"
);
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));
}
function safeIncreaseAllowance(
IERC20 token,
address spender,
uint256 value
) internal {
uint256 newAllowance = token.allowance(address(this), spender) + value;
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
}
function safeDecreaseAllowance(
IERC20 token,
address spender,
uint256 value
) internal {
unchecked {
uint256 oldAllowance = token.allowance(address(this), spender);
require(oldAllowance >= value, "SafeERC20: decreased allowance below zero");
uint256 newAllowance = oldAllowance - value;
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
}
}
function _callOptionalReturn(IERC20 token, bytes memory data) private {
bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed");
if (returndata.length > 0) {
require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed");
}
}
}
{
"compilationTarget": {
"contracts/CrvDepositorWrapper.sol": "CrvDepositorWrapper"
},
"evmVersion": "london",
"libraries": {},
"metadata": {
"bytecodeHash": "none"
},
"optimizer": {
"enabled": true,
"runs": 800
},
"remappings": []
}
[{"inputs":[{"internalType":"address","name":"_crvDeposit","type":"address"},{"internalType":"contract IVault","name":"_balancerVault","type":"address"},{"internalType":"address","name":"_bal","type":"address"},{"internalType":"address","name":"_weth","type":"address"},{"internalType":"bytes32","name":"_balETHPoolId","type":"bytes32"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"BAL","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"BALANCER_POOL_TOKEN","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"BALANCER_VAULT","outputs":[{"internalType":"contract IVault","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"BAL_ETH_POOL_ID","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"WETH","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"crvDeposit","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"uint256","name":"_minOut","type":"uint256"},{"internalType":"bool","name":"_lock","type":"bool"},{"internalType":"address","name":"_stakeAddress","type":"address"}],"name":"deposit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"uint256","name":"_outputBps","type":"uint256"}],"name":"getMinOut","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"setApprovals","outputs":[],"stateMutability":"nonpayable","type":"function"}]