编译器
0.8.11+commit.d7f03943
文件 1 的 12:Address.sol
pragma solidity ^0.8.1;
library Address {
function isContract(address account) internal view returns (bool) {
return account.code.length > 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 的 12:Context.sol
pragma solidity ^0.8.0;
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
}
文件 3 的 12:Convex.sol
pragma solidity ^0.8.11;
interface IConvexRewardPool {
function rewardToken() external view returns (address);
function balanceOf(address account) external view returns (uint256);
function extraRewardsLength() external view returns (uint256);
function extraRewards(uint256 idx) external view returns (address);
function getReward(address _user, bool _extra) external returns (bool);
function stake(uint256 _amount) external returns (bool);
function withdraw(uint256 _amount, bool _claim) external returns (bool);
}
文件 4 的 12:ERC20.sol
pragma solidity ^0.8.0;
import "./IERC20.sol";
import "./extensions/IERC20Metadata.sol";
import "../../utils/Context.sol";
contract ERC20 is Context, IERC20, IERC20Metadata {
mapping(address => uint256) private _balances;
mapping(address => mapping(address => uint256)) private _allowances;
uint256 private _totalSupply;
string private _name;
string private _symbol;
constructor(string memory name_, string memory symbol_) {
_name = name_;
_symbol = symbol_;
}
function name() public view virtual override returns (string memory) {
return _name;
}
function symbol() public view virtual override returns (string memory) {
return _symbol;
}
function decimals() public view virtual override returns (uint8) {
return 18;
}
function totalSupply() public view virtual override returns (uint256) {
return _totalSupply;
}
function balanceOf(address account) public view virtual override returns (uint256) {
return _balances[account];
}
function transfer(address to, uint256 amount) public virtual override returns (bool) {
address owner = _msgSender();
_transfer(owner, to, amount);
return true;
}
function allowance(address owner, address spender) public view virtual override returns (uint256) {
return _allowances[owner][spender];
}
function approve(address spender, uint256 amount) public virtual override returns (bool) {
address owner = _msgSender();
_approve(owner, spender, amount);
return true;
}
function transferFrom(
address from,
address to,
uint256 amount
) public virtual override returns (bool) {
address spender = _msgSender();
_spendAllowance(from, spender, amount);
_transfer(from, to, amount);
return true;
}
function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {
address owner = _msgSender();
_approve(owner, spender, _allowances[owner][spender] + addedValue);
return true;
}
function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {
address owner = _msgSender();
uint256 currentAllowance = _allowances[owner][spender];
require(currentAllowance >= subtractedValue, "ERC20: decreased allowance below zero");
unchecked {
_approve(owner, spender, currentAllowance - subtractedValue);
}
return true;
}
function _transfer(
address from,
address to,
uint256 amount
) internal virtual {
require(from != address(0), "ERC20: transfer from the zero address");
require(to != address(0), "ERC20: transfer to the zero address");
_beforeTokenTransfer(from, to, amount);
uint256 fromBalance = _balances[from];
require(fromBalance >= amount, "ERC20: transfer amount exceeds balance");
unchecked {
_balances[from] = fromBalance - amount;
}
_balances[to] += amount;
emit Transfer(from, to, amount);
_afterTokenTransfer(from, to, amount);
}
function _mint(address account, uint256 amount) internal virtual {
require(account != address(0), "ERC20: mint to the zero address");
_beforeTokenTransfer(address(0), account, amount);
_totalSupply += amount;
_balances[account] += amount;
emit Transfer(address(0), account, amount);
_afterTokenTransfer(address(0), account, amount);
}
function _burn(address account, uint256 amount) internal virtual {
require(account != address(0), "ERC20: burn from the zero address");
_beforeTokenTransfer(account, address(0), amount);
uint256 accountBalance = _balances[account];
require(accountBalance >= amount, "ERC20: burn amount exceeds balance");
unchecked {
_balances[account] = accountBalance - amount;
}
_totalSupply -= amount;
emit Transfer(account, address(0), amount);
_afterTokenTransfer(account, address(0), amount);
}
function _approve(
address owner,
address spender,
uint256 amount
) internal virtual {
require(owner != address(0), "ERC20: approve from the zero address");
require(spender != address(0), "ERC20: approve to the zero address");
_allowances[owner][spender] = amount;
emit Approval(owner, spender, amount);
}
function _spendAllowance(
address owner,
address spender,
uint256 amount
) internal virtual {
uint256 currentAllowance = allowance(owner, spender);
if (currentAllowance != type(uint256).max) {
require(currentAllowance >= amount, "ERC20: insufficient allowance");
unchecked {
_approve(owner, spender, currentAllowance - amount);
}
}
}
function _beforeTokenTransfer(
address from,
address to,
uint256 amount
) internal virtual {}
function _afterTokenTransfer(
address from,
address to,
uint256 amount
) internal virtual {}
}
文件 5 的 12:Governable.sol
pragma solidity ^0.8.11;
contract Governable {
address payable private _governor;
address payable private _pendingGovernor;
event OwnershipTransferred(address indexed previousGovernor, address indexed newGovernor);
event PendingOwnershipTransfer(address indexed from, address indexed to);
function initializeGovernable(address _newGovernor) internal {
require(_governor == address(0), "already initialized");
_governor = payable(_newGovernor);
emit OwnershipTransferred(address(0), _newGovernor);
}
function governor() public view returns (address payable) {
return _governor;
}
modifier onlyGov() {
require(isGov(), "msg.sender is not owner");
_;
}
function isGov() public view returns (bool) {
return msg.sender == _governor;
}
function transferOwnership(address payable newGovernor) public onlyGov {
_pendingGovernor = newGovernor;
emit PendingOwnershipTransfer(_governor, newGovernor);
}
function receiveOwnership() public {
require(msg.sender == _pendingGovernor, "Only pending governor can call this function");
_transferOwnership(_pendingGovernor);
_pendingGovernor = payable(address(0));
}
function _transferOwnership(address payable newGovernor) internal {
require(newGovernor != address(0));
emit OwnershipTransferred(_governor, newGovernor);
_governor = newGovernor;
}
uint256[50] private __gap;
}
文件 6 的 12: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 to, 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 from,
address to,
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);
}
文件 7 的 12:IERC20Metadata.sol
pragma solidity ^0.8.0;
import "../IERC20.sol";
interface IERC20Metadata is IERC20 {
function name() external view returns (string memory);
function symbol() external view returns (string memory);
function decimals() external view returns (uint8);
}
文件 8 的 12:IRcaController.sol
pragma solidity ^0.8.11;
interface IRcaController {
function mint(
address user,
uint256 uAmount,
uint256 expiry,
uint8 v,
bytes32 r,
bytes32 s,
uint256 _newCumLiq,
bytes32[] calldata cumLiqProof
) external;
function redeemRequest(
address user,
uint256 _newCumLiq,
bytes32[] calldata cumLiqProof,
uint256 _newPercentReserved,
bytes32[] calldata _percentReservedProof
) external;
function redeemFinalize(
address user,
address _to,
uint256 _newCumLiq,
bytes32[] calldata cumLiqProof,
uint256 _newPercentReserved,
bytes32[] calldata _percentReservedProof
) external returns (bool);
function purchase(
address user,
address uToken,
uint256 uEthPrice,
bytes32[] calldata priceProof,
uint256 _newCumLiq,
bytes32[] calldata cumLiqProof
) external;
function verifyLiq(
address shield,
uint256 _newCumLiq,
bytes32[] memory cumLiqProof
) external view;
function verifyPrice(
address shield,
uint256 _value,
bytes32[] memory _proof
) external view;
function apr() external view returns (uint256);
function getAprUpdate() external view returns (uint32);
function systemUpdates()
external
view
returns (
uint32,
uint32,
uint32,
uint32,
uint32,
uint32
);
}
文件 9 的 12:IRouter.sol
pragma solidity ^0.8.11;
interface IRouter {
function routeTo(
address user,
uint256 uAmount,
bytes calldata data
) external;
}
文件 10 的 12:RcaShieldBase.sol
pragma solidity 0.8.11;
import "../general/Governable.sol";
import "../interfaces/IRouter.sol";
import "../interfaces/IRcaController.sol";
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
abstract contract RcaShieldBase is ERC20, Governable {
using SafeERC20 for IERC20Metadata;
uint256 constant YEAR_SECS = 31536000;
uint256 constant DENOMINATOR = 10000;
uint256 constant BUFFER = 1e18;
IRcaController public controller;
IERC20Metadata public immutable uToken;
uint256 public apr;
uint256 public discount;
address payable public treasury;
uint256 public percentReserved;
uint256 public cumLiqForClaims;
uint256 public amtForSale;
uint256 public pendingWithdrawal;
uint256 public withdrawalDelay;
mapping(address => WithdrawRequest) public withdrawRequests;
uint256 lastUpdate;
struct WithdrawRequest {
uint112 uAmount;
uint112 rcaAmount;
uint32 endTime;
}
event Mint(
address indexed sender,
address indexed to,
address indexed referrer,
uint256 uAmount,
uint256 rcaAmount,
uint256 timestamp
);
event RedeemRequest(address indexed user, uint256 uAmount, uint256 rcaAmount, uint256 endTime, uint256 timestamp);
event RedeemFinalize(
address indexed user,
address indexed to,
uint256 uAmount,
uint256 rcaAmount,
uint256 timestamp
);
event PurchaseU(address indexed to, uint256 uAmount, uint256 ethAmount, uint256 price, uint256 timestamp);
event PurchaseRca(
address indexed to,
uint256 uAmount,
uint256 rcaAmount,
uint256 ethAmount,
uint256 price,
uint256 timestamp
);
modifier onlyController() {
require(msg.sender == address(controller), "Function must only be called by controller.");
_;
}
constructor(
string memory _name,
string memory _symbol,
address _uToken,
address _governor,
address _controller
) ERC20(_name, _symbol) {
initializeGovernable(_governor);
uToken = IERC20Metadata(_uToken);
controller = IRcaController(_controller);
}
function initialize(
uint256 _apr,
uint256 _discount,
address payable _treasury,
uint256 _withdrawalDelay
) external onlyController {
require(treasury == address(0), "Contract has already been initialized.");
apr = _apr;
discount = _discount;
treasury = _treasury;
withdrawalDelay = _withdrawalDelay;
lastUpdate = block.timestamp;
}
function mintTo(
address _user,
address _referrer,
uint256 _uAmount,
uint256 _expiry,
uint8 _v,
bytes32 _r,
bytes32 _s,
uint256 _newCumLiqForClaims,
bytes32[] calldata _liqForClaimsProof
) external virtual {
controller.mint(_user, _uAmount, _expiry, _v, _r, _s, _newCumLiqForClaims, _liqForClaimsProof);
_update();
uint256 rcaAmount = _rcaValue(_uAmount, amtForSale);
uToken.safeTransferFrom(msg.sender, address(this), _uAmount);
_mint(_user, rcaAmount);
_afterMint(_uAmount);
emit Mint(msg.sender, _user, _referrer, _uAmount, rcaAmount, block.timestamp);
}
function redeemRequest(
uint256 _rcaAmount,
uint256 _newCumLiqForClaims,
bytes32[] calldata _liqForClaimsProof,
uint256 _newPercentReserved,
bytes32[] calldata _percentReservedProof
) external {
controller.redeemRequest(
msg.sender,
_newCumLiqForClaims,
_liqForClaimsProof,
_newPercentReserved,
_percentReservedProof
);
_update();
uint256 uAmount = _uValue(_rcaAmount, amtForSale, percentReserved);
_burn(msg.sender, _rcaAmount);
_afterRedeem(uAmount);
pendingWithdrawal += _rcaAmount;
WithdrawRequest memory curRequest = withdrawRequests[msg.sender];
uint112 newUAmount = uint112(uAmount) + curRequest.uAmount;
uint112 newRcaAmount = uint112(_rcaAmount) + curRequest.rcaAmount;
uint32 endTime = uint32(block.timestamp) + uint32(withdrawalDelay);
withdrawRequests[msg.sender] = WithdrawRequest(newUAmount, newRcaAmount, endTime);
emit RedeemRequest(msg.sender, uint256(uAmount), _rcaAmount, uint256(endTime), block.timestamp);
}
function redeemFinalize(
address _to,
bytes calldata _routerData,
uint256 _newCumLiqForClaims,
bytes32[] calldata _liqForClaimsProof,
uint256 _newPercentReserved,
bytes32[] calldata _percentReservedProof
) external virtual {
address user = msg.sender;
WithdrawRequest memory request = withdrawRequests[user];
delete withdrawRequests[user];
require(request.endTime > 0 && uint32(block.timestamp) > request.endTime, "Withdrawal not yet allowed.");
bool isRouterVerified = controller.redeemFinalize(
user,
_to,
_newCumLiqForClaims,
_liqForClaimsProof,
_newPercentReserved,
_percentReservedProof
);
_update();
uint256 uAmount = _uValue(request.rcaAmount, amtForSale, percentReserved);
if (request.uAmount < uAmount) uAmount = uint256(request.uAmount);
pendingWithdrawal -= uint256(request.rcaAmount);
uToken.safeTransfer(_to, uAmount);
if (isRouterVerified) IRouter(_to).routeTo(user, uAmount, _routerData);
emit RedeemFinalize(user, _to, uAmount, uint256(request.rcaAmount), block.timestamp);
}
function purchaseU(
address _user,
uint256 _uAmount,
uint256 _uEthPrice,
bytes32[] calldata _priceProof,
uint256 _newCumLiqForClaims,
bytes32[] calldata _liqForClaimsProof
) external payable virtual {
controller.purchase(_user, address(uToken), _uEthPrice, _priceProof, _newCumLiqForClaims, _liqForClaimsProof);
_update();
uint256 price = _uEthPrice - ((_uEthPrice * discount) / DENOMINATOR);
uint256 ethAmount = (price * _uAmount) / 1 ether;
require(msg.value == ethAmount, "Incorrect Ether sent.");
amtForSale -= _uAmount;
uToken.safeTransfer(_user, _uAmount);
treasury.transfer(msg.value);
emit PurchaseU(_user, _uAmount, ethAmount, _uEthPrice, block.timestamp);
}
function purchaseRca(
address _user,
uint256 _uAmount,
uint256 _uEthPrice,
bytes32[] calldata _priceProof,
uint256 _newCumLiqForClaims,
bytes32[] calldata _liqForClaimsProof
) external payable {
controller.purchase(_user, address(uToken), _uEthPrice, _priceProof, _newCumLiqForClaims, _liqForClaimsProof);
_update();
uint256 price = _uEthPrice - ((_uEthPrice * discount) / DENOMINATOR);
uint256 ethAmount = (price * _uAmount) / 1 ether;
require(msg.value == ethAmount, "Incorrect Ether sent.");
uint256 rcaAmount = _rcaValue(_uAmount, amtForSale);
amtForSale -= _uAmount;
_mint(_user, rcaAmount);
treasury.transfer(msg.value);
emit PurchaseRca(_user, _uAmount, rcaAmount, _uEthPrice, ethAmount, block.timestamp);
}
function uValue(
uint256 _rcaAmount,
uint256 _cumLiqForClaims,
uint256 _percentReserved
) external view returns (uint256 uAmount) {
uint256 extraForSale = getExtraForSale(_cumLiqForClaims);
uAmount = _uValue(_rcaAmount, amtForSale + extraForSale, _percentReserved);
}
function rcaValue(uint256 _uAmount, uint256 _cumLiqForClaims) external view returns (uint256 rcaAmount) {
uint256 extraForSale = getExtraForSale(_cumLiqForClaims);
rcaAmount = _rcaValue(_uAmount, amtForSale + extraForSale);
}
function _uValue(
uint256 _rcaAmount,
uint256 _totalForSale,
uint256 _percentReserved
) internal view returns (uint256 uAmount) {
uint256 balance = _uBalance();
if (totalSupply() == 0) return _rcaAmount;
else if (balance < _totalForSale) return 0;
uAmount = ((balance - _totalForSale) * _rcaAmount) / (totalSupply() + pendingWithdrawal);
if (_percentReserved > 0) uAmount -= ((uAmount * _percentReserved) / DENOMINATOR);
}
function _rcaValue(uint256 _uAmount, uint256 _totalForSale) internal view virtual returns (uint256 rcaAmount) {
uint256 balance = _uBalance();
if (balance == 0 || totalSupply() == 0 || balance < _totalForSale) return _uAmount;
rcaAmount = ((totalSupply() + pendingWithdrawal) * _uAmount) / (balance - _totalForSale);
}
function getExtraForSale(uint256 _newCumLiqForClaims) public view returns (uint256 extraForSale) {
uint256 extraLiqForClaims = _newCumLiqForClaims - cumLiqForClaims;
uint256 extraFees = _getInterimFees(controller.apr(), uint256(controller.getAprUpdate()));
extraForSale = extraFees + extraLiqForClaims;
return extraForSale;
}
function _getInterimFees(uint256 _newApr, uint256 _aprUpdate) internal view returns (uint256 fees) {
uint256 balance = _uBalance();
uint256 aprAvg = apr * BUFFER;
uint256 totalTimeElapsed = block.timestamp - lastUpdate;
if (_aprUpdate > lastUpdate) {
uint256 aprPrev = apr * (_aprUpdate - lastUpdate);
uint256 aprCur = _newApr * (block.timestamp - _aprUpdate);
aprAvg = ((aprPrev + aprCur) * BUFFER) / totalTimeElapsed;
}
if (balance < amtForSale) return 0;
uint256 activeInclReserved = balance - amtForSale;
fees = (activeInclReserved * aprAvg * totalTimeElapsed) / YEAR_SECS / DENOMINATOR / BUFFER;
}
function uBalance() external view returns (uint256) {
return _uBalance();
}
function _update() internal {
if (apr > 0) {
uint256 balance = _uBalance();
if (balance < amtForSale) return;
uint256 secsElapsed = block.timestamp - lastUpdate;
uint256 active = balance - amtForSale;
uint256 activeExclReserved = active - ((active * percentReserved) / DENOMINATOR);
amtForSale += (activeExclReserved * secsElapsed * apr) / YEAR_SECS / DENOMINATOR;
}
lastUpdate = block.timestamp;
}
function _uBalance() internal view virtual returns (uint256);
function _afterMint(uint256 _uAmount) internal virtual;
function _afterRedeem(uint256 _uAmount) internal virtual;
function controllerUpdate(uint256 _newApr, uint256 _aprUpdate) external onlyController {
uint256 extraFees = _getInterimFees(_newApr, _aprUpdate);
amtForSale += extraFees;
lastUpdate = block.timestamp;
}
function setLiqForClaims(uint256 _newCumLiqForClaims) external onlyController {
if (_newCumLiqForClaims > cumLiqForClaims) {
amtForSale += _newCumLiqForClaims - cumLiqForClaims;
} else {
uint256 subtrahend = cumLiqForClaims - _newCumLiqForClaims;
amtForSale = amtForSale > subtrahend ? amtForSale - subtrahend : 0;
}
require(_uBalance() >= amtForSale, "amtForSale is too high.");
cumLiqForClaims = _newCumLiqForClaims;
}
function setTreasury(address _newTreasury) external onlyController {
treasury = payable(_newTreasury);
}
function setPercentReserved(uint256 _newPercentReserved) external onlyController {
if (_newPercentReserved > 3300) {
percentReserved = 3300;
} else {
percentReserved = _newPercentReserved;
}
}
function setWithdrawalDelay(uint256 _newWithdrawalDelay) external onlyController {
withdrawalDelay = _newWithdrawalDelay;
}
function setDiscount(uint256 _newDiscount) external onlyController {
discount = _newDiscount;
}
function setApr(uint256 _newApr) external onlyController {
apr = _newApr;
}
function setController(address _newController) external onlyGov {
controller = IRcaController(_newController);
}
function proofOfLoss(address payable _coverAddress) external onlyGov {
_coverAddress.transfer(0);
}
}
文件 11 的 12:RcaShieldConvex.sol
pragma solidity ^0.8.11;
import "../RcaShieldBase.sol";
import "../../external/Convex.sol";
contract RcaShieldConvex is RcaShieldBase {
using SafeERC20 for IERC20Metadata;
IConvexRewardPool public immutable rewardPool;
constructor(
string memory _name,
string memory _symbol,
address _uToken,
address _governance,
address _controller,
IConvexRewardPool _rewardPool
) RcaShieldBase(_name, _symbol, _uToken, _governance, _controller) {
rewardPool = _rewardPool;
uToken.safeApprove(address(rewardPool), type(uint256).max);
}
function getReward() external {
rewardPool.getReward(address(this), true);
}
function purchase(
address _token,
uint256 _amount,
uint256 _tokenPrice,
bytes32[] calldata _tokenPriceProof,
uint256 _underlyingPrice,
bytes32[] calldata _underlyinPriceProof
) external {
require(_token != address(uToken), "cannot buy underlying token");
controller.verifyPrice(_token, _tokenPrice, _tokenPriceProof);
controller.verifyPrice(address(uToken), _underlyingPrice, _underlyinPriceProof);
uint256 underlyingAmount = (_amount * _tokenPrice) / _underlyingPrice;
if (discount > 0) {
underlyingAmount -= (underlyingAmount * discount) / DENOMINATOR;
}
IERC20Metadata(_token).safeTransfer(msg.sender, _amount);
uToken.safeTransferFrom(msg.sender, address(this), underlyingAmount);
rewardPool.stake(underlyingAmount);
}
function _uBalance() internal view override returns (uint256) {
return uToken.balanceOf(address(this)) + rewardPool.balanceOf(address(this));
}
function _afterMint(uint256 _uAmount) internal override {
rewardPool.stake(_uAmount);
}
function _afterRedeem(uint256 _uAmount) internal override {
rewardPool.withdraw(_uAmount, false);
}
}
文件 12 的 12: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/core/adapters/RcaShieldConvex.sol": "RcaShieldConvex"
},
"evmVersion": "london",
"libraries": {},
"metadata": {
"bytecodeHash": "none"
},
"optimizer": {
"enabled": true,
"runs": 200
},
"remappings": []
}
[{"inputs":[{"internalType":"string","name":"_name","type":"string"},{"internalType":"string","name":"_symbol","type":"string"},{"internalType":"address","name":"_uToken","type":"address"},{"internalType":"address","name":"_governance","type":"address"},{"internalType":"address","name":"_controller","type":"address"},{"internalType":"contract IConvexRewardPool","name":"_rewardPool","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"address","name":"referrer","type":"address"},{"indexed":false,"internalType":"uint256","name":"uAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"rcaAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"Mint","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousGovernor","type":"address"},{"indexed":true,"internalType":"address","name":"newGovernor","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"}],"name":"PendingOwnershipTransfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"uAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"rcaAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"ethAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"price","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"PurchaseRca","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"uAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"ethAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"price","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"PurchaseU","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"uAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"rcaAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"RedeemFinalize","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"uAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"rcaAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"endTime","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"RedeemRequest","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"amtForSale","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"apr","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"controller","outputs":[{"internalType":"contract IRcaController","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_newApr","type":"uint256"},{"internalType":"uint256","name":"_aprUpdate","type":"uint256"}],"name":"controllerUpdate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"cumLiqForClaims","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"subtractedValue","type":"uint256"}],"name":"decreaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"discount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_newCumLiqForClaims","type":"uint256"}],"name":"getExtraForSale","outputs":[{"internalType":"uint256","name":"extraForSale","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getReward","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"governor","outputs":[{"internalType":"address payable","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"addedValue","type":"uint256"}],"name":"increaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_apr","type":"uint256"},{"internalType":"uint256","name":"_discount","type":"uint256"},{"internalType":"address payable","name":"_treasury","type":"address"},{"internalType":"uint256","name":"_withdrawalDelay","type":"uint256"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"isGov","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"},{"internalType":"address","name":"_referrer","type":"address"},{"internalType":"uint256","name":"_uAmount","type":"uint256"},{"internalType":"uint256","name":"_expiry","type":"uint256"},{"internalType":"uint8","name":"_v","type":"uint8"},{"internalType":"bytes32","name":"_r","type":"bytes32"},{"internalType":"bytes32","name":"_s","type":"bytes32"},{"internalType":"uint256","name":"_newCumLiqForClaims","type":"uint256"},{"internalType":"bytes32[]","name":"_liqForClaimsProof","type":"bytes32[]"}],"name":"mintTo","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pendingWithdrawal","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"percentReserved","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address payable","name":"_coverAddress","type":"address"}],"name":"proofOfLoss","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"uint256","name":"_tokenPrice","type":"uint256"},{"internalType":"bytes32[]","name":"_tokenPriceProof","type":"bytes32[]"},{"internalType":"uint256","name":"_underlyingPrice","type":"uint256"},{"internalType":"bytes32[]","name":"_underlyinPriceProof","type":"bytes32[]"}],"name":"purchase","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"},{"internalType":"uint256","name":"_uAmount","type":"uint256"},{"internalType":"uint256","name":"_uEthPrice","type":"uint256"},{"internalType":"bytes32[]","name":"_priceProof","type":"bytes32[]"},{"internalType":"uint256","name":"_newCumLiqForClaims","type":"uint256"},{"internalType":"bytes32[]","name":"_liqForClaimsProof","type":"bytes32[]"}],"name":"purchaseRca","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"},{"internalType":"uint256","name":"_uAmount","type":"uint256"},{"internalType":"uint256","name":"_uEthPrice","type":"uint256"},{"internalType":"bytes32[]","name":"_priceProof","type":"bytes32[]"},{"internalType":"uint256","name":"_newCumLiqForClaims","type":"uint256"},{"internalType":"bytes32[]","name":"_liqForClaimsProof","type":"bytes32[]"}],"name":"purchaseU","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_uAmount","type":"uint256"},{"internalType":"uint256","name":"_cumLiqForClaims","type":"uint256"}],"name":"rcaValue","outputs":[{"internalType":"uint256","name":"rcaAmount","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"receiveOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_to","type":"address"},{"internalType":"bytes","name":"_routerData","type":"bytes"},{"internalType":"uint256","name":"_newCumLiqForClaims","type":"uint256"},{"internalType":"bytes32[]","name":"_liqForClaimsProof","type":"bytes32[]"},{"internalType":"uint256","name":"_newPercentReserved","type":"uint256"},{"internalType":"bytes32[]","name":"_percentReservedProof","type":"bytes32[]"}],"name":"redeemFinalize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_rcaAmount","type":"uint256"},{"internalType":"uint256","name":"_newCumLiqForClaims","type":"uint256"},{"internalType":"bytes32[]","name":"_liqForClaimsProof","type":"bytes32[]"},{"internalType":"uint256","name":"_newPercentReserved","type":"uint256"},{"internalType":"bytes32[]","name":"_percentReservedProof","type":"bytes32[]"}],"name":"redeemRequest","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"rewardPool","outputs":[{"internalType":"contract IConvexRewardPool","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_newApr","type":"uint256"}],"name":"setApr","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_newController","type":"address"}],"name":"setController","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_newDiscount","type":"uint256"}],"name":"setDiscount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_newCumLiqForClaims","type":"uint256"}],"name":"setLiqForClaims","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_newPercentReserved","type":"uint256"}],"name":"setPercentReserved","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_newTreasury","type":"address"}],"name":"setTreasury","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_newWithdrawalDelay","type":"uint256"}],"name":"setWithdrawalDelay","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address payable","name":"newGovernor","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"treasury","outputs":[{"internalType":"address payable","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"uBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"uToken","outputs":[{"internalType":"contract IERC20Metadata","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_rcaAmount","type":"uint256"},{"internalType":"uint256","name":"_cumLiqForClaims","type":"uint256"},{"internalType":"uint256","name":"_percentReserved","type":"uint256"}],"name":"uValue","outputs":[{"internalType":"uint256","name":"uAmount","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"withdrawRequests","outputs":[{"internalType":"uint112","name":"uAmount","type":"uint112"},{"internalType":"uint112","name":"rcaAmount","type":"uint112"},{"internalType":"uint32","name":"endTime","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"withdrawalDelay","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"}]