编译器
0.8.19+commit.7dd6d404
文件 1 的 15: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 functionCallWithValue(target, data, 0, "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");
(bool success, bytes memory returndata) = target.call{value: value}(data);
return verifyCallResultFromTarget(target, 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) {
(bool success, bytes memory returndata) = target.staticcall(data);
return verifyCallResultFromTarget(target, 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) {
(bool success, bytes memory returndata) = target.delegatecall(data);
return verifyCallResultFromTarget(target, success, returndata, errorMessage);
}
function verifyCallResultFromTarget(
address target,
bool success,
bytes memory returndata,
string memory errorMessage
) internal view returns (bytes memory) {
if (success) {
if (returndata.length == 0) {
require(isContract(target), "Address: call to non-contract");
}
return returndata;
} else {
_revert(returndata, errorMessage);
}
}
function verifyCallResult(
bool success,
bytes memory returndata,
string memory errorMessage
) internal pure returns (bytes memory) {
if (success) {
return returndata;
} else {
_revert(returndata, errorMessage);
}
}
function _revert(bytes memory returndata, string memory errorMessage) private pure {
if (returndata.length > 0) {
assembly {
let returndata_size := mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert(errorMessage);
}
}
}
文件 2 的 15:CometExtInterface.sol
pragma solidity 0.8.19;
struct TotalsBasic {
uint64 baseSupplyIndex;
uint64 baseBorrowIndex;
uint64 trackingSupplyIndex;
uint64 trackingBorrowIndex;
uint104 totalSupplyBase;
uint104 totalBorrowBase;
uint40 lastAccrualTime;
uint8 pauseFlags;
}
abstract contract CometExtInterface {
error BadAmount();
error BadNonce();
error BadSignatory();
error InvalidValueS();
error InvalidValueV();
error SignatureExpired();
function allow(address manager, bool isAllowed) external virtual;
function allowBySig(
address owner,
address manager,
bool isAllowed,
uint256 nonce,
uint256 expiry,
uint8 v,
bytes32 r,
bytes32 s
) external virtual;
function collateralBalanceOf(address account, address asset)
external
view
virtual
returns (uint128);
function baseTrackingAccrued(address account) external view virtual returns (uint64);
function baseAccrualScale() external view virtual returns (uint64);
function baseIndexScale() external view virtual returns (uint64);
function factorScale() external view virtual returns (uint64);
function priceScale() external view virtual returns (uint64);
function maxAssets() external view virtual returns (uint8);
function totalsBasic() external view virtual returns (TotalsBasic memory);
function version() external view virtual returns (string memory);
function name() external view virtual returns (string memory);
function symbol() external view virtual returns (string memory);
function approve(address spender, uint256 amount) external virtual returns (bool);
function allowance(address owner, address spender) external view virtual returns (uint256);
event Approval(address indexed owner, address indexed spender, uint256 amount);
function hasPermission(address owner, address manager) external view virtual returns (bool);
}
文件 3 的 15:CometHelpers.sol
pragma solidity 0.8.19;
contract CometHelpers {
uint64 internal constant BASE_INDEX_SCALE = 1e15;
uint256 public constant EXP_SCALE = 1e18;
uint256 public constant BASE_SCALE = 1e6;
error InvalidUInt64();
error InvalidUInt104();
error InvalidInt256();
error NegativeNumber();
function safe64(uint256 n) internal pure returns (uint64) {
if (n > type(uint64).max) revert InvalidUInt64();
return uint64(n);
}
function presentValueSupply(uint64 baseSupplyIndex_, uint104 principalValue_)
internal
pure
returns (uint256)
{
return (uint256(principalValue_) * baseSupplyIndex_) / BASE_INDEX_SCALE;
}
function principalValueSupply(uint64 baseSupplyIndex_, uint256 presentValue_)
internal
pure
returns (uint104)
{
return safe104((presentValue_ * BASE_INDEX_SCALE) / baseSupplyIndex_);
}
function safe104(uint256 n) internal pure returns (uint104) {
if (n > type(uint104).max) revert InvalidUInt104();
return uint104(n);
}
function mulFactor(uint256 n, uint256 factor) internal pure returns (uint256) {
return (n * factor) / EXP_SCALE;
}
function divBaseWei(uint256 n, uint256 baseWei) internal pure returns (uint256) {
return (n * BASE_SCALE) / baseWei;
}
}
文件 4 的 15:CometInterface.sol
pragma solidity 0.8.19;
import "./CometMainInterface.sol";
import "./CometExtInterface.sol";
abstract contract CometInterface is CometMainInterface, CometExtInterface {
struct UserBasic {
int104 principal;
uint64 baseTrackingIndex;
uint64 baseTrackingAccrued;
}
function userBasic(address account) external view virtual returns (UserBasic memory);
}
文件 5 的 15:CometMainInterface.sol
pragma solidity 0.8.19;
struct AssetInfo {
uint8 offset;
address asset;
address priceFeed;
uint64 scale;
uint64 borrowCollateralFactor;
uint64 liquidateCollateralFactor;
uint64 liquidationFactor;
uint128 supplyCap;
}
abstract contract CometMainInterface {
error Absurd();
error AlreadyInitialized();
error BadAsset();
error BadDecimals();
error BadDiscount();
error BadMinimum();
error BadPrice();
error BorrowTooSmall();
error BorrowCFTooLarge();
error InsufficientReserves();
error LiquidateCFTooLarge();
error NoSelfTransfer();
error NotCollateralized();
error NotForSale();
error NotLiquidatable();
error Paused();
error SupplyCapExceeded();
error TimestampTooLarge();
error TooManyAssets();
error TooMuchSlippage();
error TransferInFailed();
error TransferOutFailed();
error Unauthorized();
event Supply(address indexed from, address indexed dst, uint256 amount);
event Transfer(address indexed from, address indexed to, uint256 amount);
event Withdraw(address indexed src, address indexed to, uint256 amount);
event SupplyCollateral(
address indexed from,
address indexed dst,
address indexed asset,
uint256 amount
);
event TransferCollateral(
address indexed from,
address indexed to,
address indexed asset,
uint256 amount
);
event WithdrawCollateral(
address indexed src,
address indexed to,
address indexed asset,
uint256 amount
);
event AbsorbDebt(
address indexed absorber,
address indexed borrower,
uint256 basePaidOut,
uint256 usdValue
);
event AbsorbCollateral(
address indexed absorber,
address indexed borrower,
address indexed asset,
uint256 collateralAbsorbed,
uint256 usdValue
);
event BuyCollateral(
address indexed buyer,
address indexed asset,
uint256 baseAmount,
uint256 collateralAmount
);
event PauseAction(
bool supplyPaused,
bool transferPaused,
bool withdrawPaused,
bool absorbPaused,
bool buyPaused
);
event WithdrawReserves(address indexed to, uint256 amount);
function supply(address asset, uint256 amount) external virtual;
function supplyTo(
address dst,
address asset,
uint256 amount
) external virtual;
function supplyFrom(
address from,
address dst,
address asset,
uint256 amount
) external virtual;
function transfer(address dst, uint256 amount) external virtual returns (bool);
function transferFrom(
address src,
address dst,
uint256 amount
) external virtual returns (bool);
function transferAsset(
address dst,
address asset,
uint256 amount
) external virtual;
function transferAssetFrom(
address src,
address dst,
address asset,
uint256 amount
) external virtual;
function withdraw(address asset, uint256 amount) external virtual;
function withdrawTo(
address to,
address asset,
uint256 amount
) external virtual;
function withdrawFrom(
address src,
address to,
address asset,
uint256 amount
) external virtual;
function approveThis(
address manager,
address asset,
uint256 amount
) external virtual;
function withdrawReserves(address to, uint256 amount) external virtual;
function absorb(address absorber, address[] calldata accounts) external virtual;
function buyCollateral(
address asset,
uint256 minAmount,
uint256 baseAmount,
address recipient
) external virtual;
function quoteCollateral(address asset, uint256 baseAmount)
public
view
virtual
returns (uint256);
function getAssetInfo(uint8 i) public view virtual returns (AssetInfo memory);
function getAssetInfoByAddress(address asset) public view virtual returns (AssetInfo memory);
function getReserves() public view virtual returns (int256);
function getPrice(address priceFeed) public view virtual returns (uint256);
function isBorrowCollateralized(address account) public view virtual returns (bool);
function isLiquidatable(address account) public view virtual returns (bool);
function totalSupply() external view virtual returns (uint256);
function totalBorrow() external view virtual returns (uint256);
function balanceOf(address owner) public view virtual returns (uint256);
function borrowBalanceOf(address account) public view virtual returns (uint256);
function pause(
bool supplyPaused,
bool transferPaused,
bool withdrawPaused,
bool absorbPaused,
bool buyPaused
) external virtual;
function isSupplyPaused() public view virtual returns (bool);
function isTransferPaused() public view virtual returns (bool);
function isWithdrawPaused() public view virtual returns (bool);
function isAbsorbPaused() public view virtual returns (bool);
function isBuyPaused() public view virtual returns (bool);
function accrueAccount(address account) external virtual;
function getSupplyRate(uint256 utilization) public view virtual returns (uint64);
function getBorrowRate(uint256 utilization) public view virtual returns (uint64);
function getUtilization() public view virtual returns (uint256);
function governor() external view virtual returns (address);
function pauseGuardian() external view virtual returns (address);
function baseToken() external view virtual returns (address);
function baseTokenPriceFeed() external view virtual returns (address);
function extensionDelegate() external view virtual returns (address);
function supplyKink() external view virtual returns (uint256);
function supplyPerSecondInterestRateSlopeLow() external view virtual returns (uint256);
function supplyPerSecondInterestRateSlopeHigh() external view virtual returns (uint256);
function supplyPerSecondInterestRateBase() external view virtual returns (uint256);
function borrowKink() external view virtual returns (uint256);
function borrowPerSecondInterestRateSlopeLow() external view virtual returns (uint256);
function borrowPerSecondInterestRateSlopeHigh() external view virtual returns (uint256);
function borrowPerSecondInterestRateBase() external view virtual returns (uint256);
function storeFrontPriceFactor() external view virtual returns (uint256);
function baseScale() external view virtual returns (uint256);
function trackingIndexScale() external view virtual returns (uint256);
function baseTrackingSupplySpeed() external view virtual returns (uint256);
function baseTrackingBorrowSpeed() external view virtual returns (uint256);
function baseMinForRewards() external view virtual returns (uint256);
function baseBorrowMin() external view virtual returns (uint256);
function targetReserves() external view virtual returns (uint256);
function numAssets() external view virtual returns (uint8);
function decimals() external view virtual returns (uint8);
function initializeStorage() external virtual;
}
文件 6 的 15:CusdcV3Wrapper.sol
pragma solidity 0.8.19;
import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import "./vendor/CometInterface.sol";
import "./WrappedERC20.sol";
import "./vendor/ICometRewards.sol";
import "./ICusdcV3Wrapper.sol";
import "./CometHelpers.sol";
contract CusdcV3Wrapper is ICusdcV3Wrapper, WrappedERC20, CometHelpers {
using SafeERC20 for IERC20;
uint256 public constant TRACKING_INDEX_SCALE = 1e15;
uint256 public constant RESCALE_FACTOR = 1e12;
CometInterface public immutable underlyingComet;
ICometRewards public immutable rewardsAddr;
IERC20 public immutable rewardERC20;
mapping(address => uint64) public baseTrackingIndex;
mapping(address => uint256) public baseTrackingAccrued;
mapping(address => uint256) public rewardsClaimed;
constructor(
address cusdcv3,
address rewardsAddr_,
address rewardERC20_
) WrappedERC20("Wrapped cUSDCv3", "wcUSDCv3") {
if (cusdcv3 == address(0)) revert ZeroAddress();
rewardsAddr = ICometRewards(rewardsAddr_);
rewardERC20 = IERC20(rewardERC20_);
underlyingComet = CometInterface(cusdcv3);
}
function decimals() public pure override(IERC20Metadata, WrappedERC20) returns (uint8) {
return 6;
}
function deposit(uint256 amount) external {
_deposit(msg.sender, msg.sender, msg.sender, amount);
}
function depositTo(address dst, uint256 amount) external {
_deposit(msg.sender, msg.sender, dst, amount);
}
function depositFrom(
address src,
address dst,
uint256 amount
) external {
_deposit(msg.sender, src, dst, amount);
}
function _deposit(
address operator,
address src,
address dst,
uint256 amount
) internal {
if (!underlyingComet.hasPermission(src, operator)) revert Unauthorized();
uint256 srcBal = underlyingComet.balanceOf(src);
if (amount > srcBal) amount = srcBal;
if (amount == 0) revert BadAmount();
underlyingComet.accrueAccount(address(this));
underlyingComet.accrueAccount(src);
CometInterface.UserBasic memory wrappedBasic = underlyingComet.userBasic(address(this));
int104 wrapperPrePrinc = wrappedBasic.principal;
IERC20(address(underlyingComet)).safeTransferFrom(src, address(this), amount);
wrappedBasic = underlyingComet.userBasic(address(this));
int104 wrapperPostPrinc = wrappedBasic.principal;
accrueAccountRewards(dst);
_mint(dst, uint104(wrapperPostPrinc - wrapperPrePrinc));
}
function withdraw(uint256 amount) external {
_withdraw(msg.sender, msg.sender, msg.sender, amount);
}
function withdrawTo(address dst, uint256 amount) external {
_withdraw(msg.sender, msg.sender, dst, amount);
}
function withdrawFrom(
address src,
address dst,
uint256 amount
) external {
_withdraw(msg.sender, src, dst, amount);
}
function _withdraw(
address operator,
address src,
address dst,
uint256 amount
) internal {
if (!hasPermission(src, operator)) revert Unauthorized();
uint256 srcBalUnderlying = underlyingBalanceOf(src);
if (srcBalUnderlying < amount) amount = srcBalUnderlying;
if (amount == 0) revert BadAmount();
underlyingComet.accrueAccount(address(this));
underlyingComet.accrueAccount(src);
uint256 srcBalPre = balanceOf(src);
CometInterface.UserBasic memory wrappedBasic = underlyingComet.userBasic(address(this));
int104 wrapperPrePrinc = wrappedBasic.principal;
IERC20(address(underlyingComet)).safeTransfer(dst, (amount / 10) * 10);
wrappedBasic = underlyingComet.userBasic(address(this));
int104 wrapperPostPrinc = wrappedBasic.principal;
uint256 burnAmt = uint256(uint104(wrapperPrePrinc - wrapperPostPrinc));
if (srcBalPre <= burnAmt) burnAmt = srcBalPre;
accrueAccountRewards(src);
_burn(src, safe104(burnAmt));
}
function _beforeTokenTransfer(
address src,
address dst,
uint256 amount
) internal virtual override {
underlyingComet.accrueAccount(address(this));
super._beforeTokenTransfer(src, dst, amount);
accrueAccountRewards(src);
accrueAccountRewards(dst);
}
function claimRewards() external {
claimTo(msg.sender, msg.sender);
}
function claimTo(address src, address dst) public {
if (!hasPermission(src, msg.sender)) revert Unauthorized();
accrueAccount(src);
uint256 claimed = rewardsClaimed[src];
uint256 accrued = baseTrackingAccrued[src] * RESCALE_FACTOR;
uint256 owed;
if (accrued > claimed) {
owed = accrued - claimed;
rewardsClaimed[src] = accrued;
rewardsAddr.claimTo(address(underlyingComet), address(this), address(this), true);
uint256 bal = rewardERC20.balanceOf(address(this));
if (owed > bal) owed = bal;
rewardERC20.safeTransfer(dst, owed);
}
emit RewardsClaimed(rewardERC20, owed);
}
function accrue() public {
underlyingComet.accrueAccount(address(this));
}
function accrueAccount(address account) public {
underlyingComet.accrueAccount(address(this));
accrueAccountRewards(account);
}
function underlyingBalanceOf(address account) public view returns (uint256) {
uint256 balance = balanceOf(account);
if (balance == 0) {
return 0;
}
return convertStaticToDynamic(safe104(balance));
}
function exchangeRate() public view returns (uint256) {
(uint64 baseSupplyIndex, ) = getUpdatedSupplyIndicies();
return presentValueSupply(baseSupplyIndex, safe104(10**underlyingComet.decimals()));
}
function convertStaticToDynamic(uint104 amount) public view returns (uint256) {
(uint64 baseSupplyIndex, ) = getUpdatedSupplyIndicies();
return presentValueSupply(baseSupplyIndex, amount);
}
function convertDynamicToStatic(uint256 amount) public view returns (uint104) {
(uint64 baseSupplyIndex, ) = getUpdatedSupplyIndicies();
return principalValueSupply(baseSupplyIndex, amount);
}
function getRewardOwed(address account) external view returns (uint256) {
(, uint64 trackingSupplyIndex) = getUpdatedSupplyIndicies();
uint256 indexDelta = uint256(trackingSupplyIndex - baseTrackingIndex[account]);
uint256 newBaseTrackingAccrued = baseTrackingAccrued[account] +
(safe104(balanceOf(account)) * indexDelta) /
TRACKING_INDEX_SCALE;
uint256 claimed = rewardsClaimed[account];
uint256 accrued = newBaseTrackingAccrued * RESCALE_FACTOR;
uint256 owed = accrued > claimed ? accrued - claimed : 0;
return owed;
}
function getSupplyIndices()
internal
view
returns (uint64 baseSupplyIndex_, uint64 trackingSupplyIndex_)
{
TotalsBasic memory totals = underlyingComet.totalsBasic();
baseSupplyIndex_ = totals.baseSupplyIndex;
trackingSupplyIndex_ = totals.trackingSupplyIndex;
}
function accrueAccountRewards(address account) internal {
uint256 accountBal = balanceOf(account);
(, uint64 trackingSupplyIndex) = getSupplyIndices();
uint256 indexDelta = uint256(trackingSupplyIndex - baseTrackingIndex[account]);
baseTrackingAccrued[account] += (safe104(accountBal) * indexDelta) / TRACKING_INDEX_SCALE;
baseTrackingIndex[account] = trackingSupplyIndex;
}
function getUpdatedSupplyIndicies() internal view returns (uint64, uint64) {
TotalsBasic memory totals = underlyingComet.totalsBasic();
uint40 timeDelta = uint40(block.timestamp) - totals.lastAccrualTime;
uint64 baseSupplyIndex_ = totals.baseSupplyIndex;
uint64 trackingSupplyIndex_ = totals.trackingSupplyIndex;
if (timeDelta != 0) {
uint256 baseTrackingSupplySpeed = underlyingComet.baseTrackingSupplySpeed();
uint256 utilization = underlyingComet.getUtilization();
uint256 supplyRate = underlyingComet.getSupplyRate(utilization);
baseSupplyIndex_ += safe64(mulFactor(baseSupplyIndex_, supplyRate * timeDelta));
trackingSupplyIndex_ += safe64(
divBaseWei(baseTrackingSupplySpeed * timeDelta, totals.totalSupplyBase)
);
}
return (baseSupplyIndex_, trackingSupplyIndex_);
}
}
文件 7 的 15:ICometRewards.sol
pragma solidity 0.8.19;
interface ICometRewards {
struct RewardConfig {
address token;
uint64 rescaleFactor;
bool shouldUpscale;
}
struct RewardOwed {
address token;
uint256 owed;
}
function rewardConfig(address) external view returns (RewardConfig memory);
function claim(
address comet,
address src,
bool shouldAccrue
) external;
function getRewardOwed(address comet, address account) external returns (RewardOwed memory);
function claimTo(
address comet,
address src,
address to,
bool shouldAccrue
) external;
}
文件 8 的 15:ICusdcV3Wrapper.sol
pragma solidity 0.8.19;
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol";
import "./vendor/CometInterface.sol";
import "./IWrappedERC20.sol";
import "../../../interfaces/IRewardable.sol";
interface ICusdcV3Wrapper is IWrappedERC20, IRewardable {
struct UserBasic {
uint104 principal;
uint64 baseTrackingIndex;
uint64 baseTrackingAccrued;
uint256 rewardsClaimed;
}
function deposit(uint256 amount) external;
function depositTo(address account, uint256 amount) external;
function depositFrom(
address from,
address dst,
uint256 amount
) external;
function withdraw(uint256 amount) external;
function withdrawTo(address to, uint256 amount) external;
function withdrawFrom(
address src,
address to,
uint256 amount
) external;
function claimTo(address src, address to) external;
function accrue() external;
function accrueAccount(address account) external;
function underlyingBalanceOf(address account) external view returns (uint256);
function getRewardOwed(address account) external view returns (uint256);
function exchangeRate() external view returns (uint256);
function convertStaticToDynamic(uint104 amount) external view returns (uint256);
function convertDynamicToStatic(uint256 amount) external view returns (uint104);
function baseTrackingAccrued(address account) external view returns (uint256);
function baseTrackingIndex(address account) external view returns (uint64);
function underlyingComet() external view returns (CometInterface);
function rewardERC20() external view returns (IERC20);
}
文件 9 的 15:IERC20.sol
pragma solidity ^0.8.0;
interface IERC20 {
event Transfer(address indexed from, address indexed to, uint256 value);
event Approval(address indexed owner, address indexed spender, uint256 value);
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);
}
文件 10 的 15: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);
}
文件 11 的 15:IERC20Permit.sol
pragma solidity ^0.8.0;
interface IERC20Permit {
function permit(
address owner,
address spender,
uint256 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) external;
function nonces(address owner) external view returns (uint256);
function DOMAIN_SEPARATOR() external view returns (bytes32);
}
文件 12 的 15:IRewardable.sol
pragma solidity 0.8.19;
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
interface IRewardable {
event RewardsClaimed(IERC20 indexed erc20, uint256 amount);
function claimRewards() external;
}
interface IRewardableComponent is IRewardable {
function claimRewardsSingle(IERC20 erc20) external;
}
文件 13 的 15:IWrappedERC20.sol
pragma solidity 0.8.19;
import "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol";
interface IWrappedERC20 is IERC20Metadata {
function allow(address account, bool isAllowed_) external;
function hasPermission(address owner, address manager) external view returns (bool);
function isAllowed(address first, address second) external returns (bool);
}
文件 14 的 15:SafeERC20.sol
pragma solidity ^0.8.0;
import "../IERC20.sol";
import "../extensions/IERC20Permit.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 oldAllowance = token.allowance(address(this), spender);
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance + value));
}
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");
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance - value));
}
}
function forceApprove(IERC20 token, address spender, uint256 value) internal {
bytes memory approvalCall = abi.encodeWithSelector(token.approve.selector, spender, value);
if (!_callOptionalReturnBool(token, approvalCall)) {
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, 0));
_callOptionalReturn(token, approvalCall);
}
}
function safePermit(
IERC20Permit token,
address owner,
address spender,
uint256 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) internal {
uint256 nonceBefore = token.nonces(owner);
token.permit(owner, spender, value, deadline, v, r, s);
uint256 nonceAfter = token.nonces(owner);
require(nonceAfter == nonceBefore + 1, "SafeERC20: permit did not succeed");
}
function _callOptionalReturn(IERC20 token, bytes memory data) private {
bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed");
require(returndata.length == 0 || abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed");
}
function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) {
(bool success, bytes memory returndata) = address(token).call(data);
return
success && (returndata.length == 0 || abi.decode(returndata, (bool))) && Address.isContract(address(token));
}
}
文件 15 的 15:WrappedERC20.sol
pragma solidity 0.8.19;
import "./IWrappedERC20.sol";
abstract contract WrappedERC20 is IWrappedERC20 {
error BadAmount();
error Unauthorized();
error ZeroAddress();
error ExceedsBalance(uint256 amount);
mapping(address => uint256) private _balances;
mapping(address => mapping(address => bool)) public isAllowed;
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 returns (string memory) {
return _name;
}
function symbol() public view virtual returns (string memory) {
return _symbol;
}
function decimals() public pure virtual 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) {
_transfer(msg.sender, to, amount);
return true;
}
function allowance(address owner, address spender)
public
view
virtual
override
returns (uint256)
{
return hasPermission(owner, spender) ? type(uint256).max : 0;
}
function approve(address spender, uint256 amount) public virtual override returns (bool) {
if (spender == address(0)) revert ZeroAddress();
if (amount == type(uint256).max) {
_allow(msg.sender, spender, true);
} else if (amount == 0) {
_allow(msg.sender, spender, false);
} else {
revert BadAmount();
}
return true;
}
function transferFrom(
address from,
address to,
uint256 amount
) public virtual override returns (bool) {
if (!hasPermission(from, msg.sender)) revert Unauthorized();
_transfer(from, to, amount);
return true;
}
function _transfer(
address from,
address to,
uint256 amount
) internal virtual {
if (from == address(0)) revert ZeroAddress();
if (to == address(0)) revert ZeroAddress();
_beforeTokenTransfer(from, to, amount);
uint256 fromBalance = _balances[from];
if (amount > fromBalance) revert ExceedsBalance(amount);
unchecked {
_balances[from] = fromBalance - amount;
}
_balances[to] += amount;
emit Transfer(from, to, amount);
}
function _mint(address account, uint256 amount) internal virtual {
if (account == address(0)) revert ZeroAddress();
_totalSupply += amount;
_balances[account] += amount;
emit Transfer(address(0), account, amount);
}
function _burn(address account, uint256 amount) internal virtual {
if (account == address(0)) revert ZeroAddress();
uint256 accountBalance = _balances[account];
if (amount > accountBalance) revert ExceedsBalance(amount);
unchecked {
_balances[account] = accountBalance - amount;
}
_totalSupply -= amount;
emit Transfer(account, address(0), amount);
}
function allow(address account, bool isAllowed_) external {
_allow(msg.sender, account, isAllowed_);
}
function _allow(
address owner,
address manager,
bool isAllowed_
) internal {
if (owner == address(0)) revert ZeroAddress();
if (manager == address(0)) revert ZeroAddress();
isAllowed[owner][manager] = isAllowed_;
emit Approval(owner, manager, isAllowed_ ? type(uint256).max : 0);
}
function hasPermission(address owner, address manager) public view returns (bool) {
return owner == manager || isAllowed[owner][manager];
}
function _beforeTokenTransfer(
address from,
address to,
uint256 amount
) internal virtual {}
}
{
"compilationTarget": {
"contracts/plugins/assets/compoundv3/CusdcV3Wrapper.sol": "CusdcV3Wrapper"
},
"evmVersion": "paris",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs"
},
"optimizer": {
"enabled": true,
"runs": 200
},
"remappings": []
}
[{"inputs":[{"internalType":"address","name":"cusdcv3","type":"address"},{"internalType":"address","name":"rewardsAddr_","type":"address"},{"internalType":"address","name":"rewardERC20_","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"BadAmount","type":"error"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"ExceedsBalance","type":"error"},{"inputs":[],"name":"InvalidInt256","type":"error"},{"inputs":[],"name":"InvalidUInt104","type":"error"},{"inputs":[],"name":"InvalidUInt64","type":"error"},{"inputs":[],"name":"NegativeNumber","type":"error"},{"inputs":[],"name":"Unauthorized","type":"error"},{"inputs":[],"name":"ZeroAddress","type":"error"},{"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":"contract IERC20","name":"erc20","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"RewardsClaimed","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":[],"name":"BASE_SCALE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"EXP_SCALE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"RESCALE_FACTOR","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"TRACKING_INDEX_SCALE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"accrue","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"accrueAccount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"bool","name":"isAllowed_","type":"bool"}],"name":"allow","outputs":[],"stateMutability":"nonpayable","type":"function"},{"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":[{"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":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"baseTrackingAccrued","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"baseTrackingIndex","outputs":[{"internalType":"uint64","name":"","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"claimRewards","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"src","type":"address"},{"internalType":"address","name":"dst","type":"address"}],"name":"claimTo","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"convertDynamicToStatic","outputs":[{"internalType":"uint104","name":"","type":"uint104"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint104","name":"amount","type":"uint104"}],"name":"convertStaticToDynamic","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"deposit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"src","type":"address"},{"internalType":"address","name":"dst","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"depositFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"dst","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"depositTo","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"exchangeRate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"getRewardOwed","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"manager","type":"address"}],"name":"hasPermission","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"isAllowed","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"rewardERC20","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"rewardsAddr","outputs":[{"internalType":"contract ICometRewards","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"rewardsClaimed","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","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","name":"account","type":"address"}],"name":"underlyingBalanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"underlyingComet","outputs":[{"internalType":"contract CometInterface","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"src","type":"address"},{"internalType":"address","name":"dst","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"withdrawFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"dst","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"withdrawTo","outputs":[],"stateMutability":"nonpayable","type":"function"}]