编译器
0.8.10+commit.fc410830
文件 1 的 23: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 的 23: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 的 23:Counters.sol
pragma solidity ^0.8.0;
library Counters {
struct Counter {
uint256 _value;
}
function current(Counter storage counter) internal view returns (uint256) {
return counter._value;
}
function increment(Counter storage counter) internal {
unchecked {
counter._value += 1;
}
}
function decrement(Counter storage counter) internal {
uint256 value = counter._value;
require(value > 0, "Counter: decrement overflow");
unchecked {
counter._value = value - 1;
}
}
function reset(Counter storage counter) internal {
counter._value = 0;
}
}
文件 4 的 23:DataTypes.sol
pragma solidity 0.8.10;
library DataTypes {
struct ReserveData {
uint256 reserveId;
address underlyingAsset;
address oTokenAddress;
address moneyMarketAddress;
uint128 lastSupplyIndex;
uint256 borrowingInterestPerSecond;
uint256 lastMoneyMarketBalance;
uint40 lastUpdateTimestamp;
uint256 totalBorrows;
address interestModelAddress;
uint256 treasuryFactor;
bool isMoneyMarketOn;
}
struct LoanData {
uint256 reserveId;
address nftAddress;
uint256 tokenId;
address borrower;
uint256 amount;
uint128 borrowRate;
uint128 interestPerSecond;
uint40 borrowBegin;
uint40 borrowDuration;
uint40 borrowOverdueTime;
uint40 liquidatableTime;
uint40 extendableTime;
uint40 borrowEnd;
LoanStatus status;
}
enum LoanStatus {
NONE,
BORROWING,
EXTENDABLE,
OVERDUE,
LIQUIDATABLE,
LIQUIDATING
}
struct WhitelistInfo {
bool enabled;
string name;
string symbol;
uint256 LTV;
uint256 minBorrowDuration;
uint256 maxBorrowDuration;
uint256 extendableDuration;
uint256 overdueDuration;
}
}
文件 5 的 23:ECDSA.sol
pragma solidity ^0.8.0;
library ECDSA {
enum RecoverError {
NoError,
InvalidSignature,
InvalidSignatureLength,
InvalidSignatureS,
InvalidSignatureV
}
function _throwError(RecoverError error) private pure {
if (error == RecoverError.NoError) {
return;
} else if (error == RecoverError.InvalidSignature) {
revert("ECDSA: invalid signature");
} else if (error == RecoverError.InvalidSignatureLength) {
revert("ECDSA: invalid signature length");
} else if (error == RecoverError.InvalidSignatureS) {
revert("ECDSA: invalid signature 's' value");
} else if (error == RecoverError.InvalidSignatureV) {
revert("ECDSA: invalid signature 'v' value");
}
}
function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {
if (signature.length == 65) {
bytes32 r;
bytes32 s;
uint8 v;
assembly {
r := mload(add(signature, 0x20))
s := mload(add(signature, 0x40))
v := byte(0, mload(add(signature, 0x60)))
}
return tryRecover(hash, v, r, s);
} else if (signature.length == 64) {
bytes32 r;
bytes32 vs;
assembly {
r := mload(add(signature, 0x20))
vs := mload(add(signature, 0x40))
}
return tryRecover(hash, r, vs);
} else {
return (address(0), RecoverError.InvalidSignatureLength);
}
}
function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {
(address recovered, RecoverError error) = tryRecover(hash, signature);
_throwError(error);
return recovered;
}
function tryRecover(
bytes32 hash,
bytes32 r,
bytes32 vs
) internal pure returns (address, RecoverError) {
bytes32 s;
uint8 v;
assembly {
s := and(vs, 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff)
v := add(shr(255, vs), 27)
}
return tryRecover(hash, v, r, s);
}
function recover(
bytes32 hash,
bytes32 r,
bytes32 vs
) internal pure returns (address) {
(address recovered, RecoverError error) = tryRecover(hash, r, vs);
_throwError(error);
return recovered;
}
function tryRecover(
bytes32 hash,
uint8 v,
bytes32 r,
bytes32 s
) internal pure returns (address, RecoverError) {
if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {
return (address(0), RecoverError.InvalidSignatureS);
}
if (v != 27 && v != 28) {
return (address(0), RecoverError.InvalidSignatureV);
}
address signer = ecrecover(hash, v, r, s);
if (signer == address(0)) {
return (address(0), RecoverError.InvalidSignature);
}
return (signer, RecoverError.NoError);
}
function recover(
bytes32 hash,
uint8 v,
bytes32 r,
bytes32 s
) internal pure returns (address) {
(address recovered, RecoverError error) = tryRecover(hash, v, r, s);
_throwError(error);
return recovered;
}
function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {
return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", hash));
}
function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {
return keccak256(abi.encodePacked("\x19\x01", domainSeparator, structHash));
}
}
文件 6 的 23: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 recipient, uint256 amount) public virtual override returns (bool) {
_transfer(_msgSender(), recipient, 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) {
_approve(_msgSender(), spender, amount);
return true;
}
function transferFrom(
address sender,
address recipient,
uint256 amount
) public virtual override returns (bool) {
_transfer(sender, recipient, amount);
uint256 currentAllowance = _allowances[sender][_msgSender()];
require(currentAllowance >= amount, "ERC20: transfer amount exceeds allowance");
unchecked {
_approve(sender, _msgSender(), currentAllowance - amount);
}
return true;
}
function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {
_approve(_msgSender(), spender, _allowances[_msgSender()][spender] + addedValue);
return true;
}
function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {
uint256 currentAllowance = _allowances[_msgSender()][spender];
require(currentAllowance >= subtractedValue, "ERC20: decreased allowance below zero");
unchecked {
_approve(_msgSender(), spender, currentAllowance - subtractedValue);
}
return true;
}
function _transfer(
address sender,
address recipient,
uint256 amount
) internal virtual {
require(sender != address(0), "ERC20: transfer from the zero address");
require(recipient != address(0), "ERC20: transfer to the zero address");
_beforeTokenTransfer(sender, recipient, amount);
uint256 senderBalance = _balances[sender];
require(senderBalance >= amount, "ERC20: transfer amount exceeds balance");
unchecked {
_balances[sender] = senderBalance - amount;
}
_balances[recipient] += amount;
emit Transfer(sender, recipient, amount);
_afterTokenTransfer(sender, recipient, 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 _beforeTokenTransfer(
address from,
address to,
uint256 amount
) internal virtual {}
function _afterTokenTransfer(
address from,
address to,
uint256 amount
) internal virtual {}
}
文件 7 的 23:ERC20Burnable.sol
pragma solidity ^0.8.0;
import "../ERC20.sol";
import "../../../utils/Context.sol";
abstract contract ERC20Burnable is Context, ERC20 {
function burn(uint256 amount) public virtual {
_burn(_msgSender(), amount);
}
function burnFrom(address account, uint256 amount) public virtual {
uint256 currentAllowance = allowance(account, _msgSender());
require(currentAllowance >= amount, "ERC20: burn amount exceeds allowance");
unchecked {
_approve(account, _msgSender(), currentAllowance - amount);
}
_burn(account, amount);
}
}
文件 8 的 23:ERC721Holder.sol
pragma solidity ^0.8.0;
import "../IERC721Receiver.sol";
contract ERC721Holder is IERC721Receiver {
function onERC721Received(
address,
address,
uint256,
bytes memory
) public virtual override returns (bytes4) {
return this.onERC721Received.selector;
}
}
文件 9 的 23:Errors.sol
pragma solidity 0.8.10;
library Errors {
string public constant MATH_MULTIPLICATION_OVERFLOW = '100';
string public constant MATH_ADDITION_OVERFLOW = '101';
string public constant MATH_DIVISION_BY_ZERO = '102';
string public constant ETH_TRANSFER_FAILED = '110';
string public constant RECEIVE_NOT_ALLOWED = '111';
string public constant FALLBACK_NOT_ALLOWED = '112';
string public constant APPROVAL_FAILED = '113';
string public constant SETTING_ZERO_ADDRESS_NOT_ALLOWED = '115';
string public constant SETTING_RESERVE_FACTOR_NOT_ALLOWED = '116';
string public constant SETTING_WHITELIST_INVALID_RESERVE_ID = '117';
string public constant SETTING_WHITELIST_NFT_ADDRESS_IS_ZERO = '118';
string public constant SETTING_WHITELIST_NFT_DURATION_OUT_OF_ORDER = '119';
string public constant SETTING_WHITELIST_NFT_NAME_EMPTY = '120';
string public constant SETTING_WHITELIST_NFT_SYMBOL_EMPTY = '121';
string public constant SETTING_WHITELIST_NFT_LTV_NOT_ALLOWED = '122';
string public constant ACL_ONLY_GOVERNANCE_CAN_CALL = '200';
string public constant ACL_ONLY_EMERGENCY_ADMIN_CAN_CALL = '201';
string public constant ACL_ONLY_POOL_ADMIN_CAN_CALL = '202';
string public constant ACL_ONLY_LIQUIDATOR_CAN_CALL = '203';
string public constant ACL_ONLY_AIRDROP_OPERATOR_CAN_CALL = '204';
string public constant ACL_ONLY_POOL_CAN_CALL = '205';
string public constant RESERVE_DOES_NOT_EXIST = '300';
string public constant RESERVE_LIQUIDITY_INSUFFICIENT = '301';
string public constant RESERVE_INDEX_OVERFLOW = '302';
string public constant RESERVE_SWITCH_MONEY_MARKET_STATE_ERROR = '303';
string public constant RESERVE_TREASURY_FACTOR_NOT_ALLOWED = '304';
string public constant RESERVE_TOKEN_CAN_NOT_BE_CLAIMED = '305';
string public constant AMOUNT_SCALED_IS_ZERO = '310';
string public constant AMOUNT_TRANSFER_OVERFLOW = '311';
string public constant DEPOSIT_AMOUNT_SHOULD_BE_BIGGER_THAN_ZERO = '320';
string public constant WITHDRAW_AMOUNT_NOT_ALLOWED = '321';
string public constant WITHDRAW_LIQUIDITY_NOT_SUFFICIENT = '322';
string public constant BORROW_DURATION_NOT_ALLOWED = '330';
string public constant BORROW_AMOUNT_EXCEED_BORROW_LIMIT = '331';
string public constant NFT_ADDRESS_IS_NOT_IN_WHITELIST = '332';
string public constant REPAY_STATUS_ERROR = '333';
string public constant REPAY_MSG_VALUE_ERROR = '334';
string public constant EXTEND_STATUS_ERROR = '335';
string public constant EXTEND_MSG_VALUE_ERROR = '336';
string public constant START_LIQUIDATION_STATUS_ERROR = '360';
string public constant END_LIQUIDATION_STATUS_ERROR = '361';
string public constant END_LIQUIDATION_AMOUNT_ERROR = '362';
string public constant LOAN_DOES_NOT_EXIST = '400';
string public constant LOAN_SET_STATUS_ERROR = '401';
string public constant LOAN_REPAYER_IS_NOT_OWNER = '402';
string public constant LOAN_LIQUIDATING_STATUS_CAN_NOT_BE_UPDATED = '403';
string public constant LOAN_CALLER_IS_NOT_OWNER = '404';
string public constant LOAN_COLLATERAL_NFT_CAN_NOT_BE_CLAIMED = '405';
string public constant FLASHCLAIM_EXECUTOR_ERROR = '410';
string public constant FLASHCLAIM_STATUS_ERROR = '411';
string public constant MONEY_MARKET_DEPOSIT_AMOUNT_NOT_ALLOWED = '500';
string public constant MONEY_MARKET_WITHDRAW_AMOUNT_NOT_ALLOWED = '501';
string public constant MONEY_MARKET_APPROVAL_FAILED = '502';
string public constant MONEY_MARKET_DELEGATE_CALL_ERROR = '503';
string public constant MONEY_MARKET_REQUIRE_DELEGATE_CALL = '504';
string public constant MONEY_MARKET_WITHDRAW_AMOUNT_NOT_MATCH = '505';
string public constant PRICE_ORACLE_HAS_NO_PRICE_FEED = '600';
string public constant PRICE_ORACLE_INCORRECT_TIMESTAMP = '601';
string public constant PRICE_ORACLE_PARAMS_ERROR = '602';
}
文件 10 的 23: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);
}
文件 11 的 23: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);
}
文件 12 的 23:IERC721Receiver.sol
pragma solidity ^0.8.0;
interface IERC721Receiver {
function onERC721Received(
address operator,
address from,
uint256 tokenId,
bytes calldata data
) external returns (bytes4);
}
文件 13 的 23:IOpenSkyIncentivesController.sol
pragma solidity 0.8.10;
interface IOpenSkyIncentivesController {
function handleAction(
address account,
uint256 userBalance,
uint256 totalSupply
) external;
function getRewardsBalance(address[] calldata assets, address user) external view returns (uint256);
function claimRewards(
address[] calldata assets,
uint256 amount,
address to,
bool stake
) external returns (uint256);
}
文件 14 的 23:IOpenSkyMoneyMarket.sol
pragma solidity 0.8.10;
interface IOpenSkyMoneyMarket {
function depositCall(address asset, uint256 amount) external;
function withdrawCall(address asset, uint256 amount, address to) external;
function getMoneyMarketToken(address asset) external view returns (address);
function getBalance(address asset, address account) external view returns (uint256);
function getSupplyRate(address asset) external view returns (uint256);
}
文件 15 的 23:IOpenSkyOToken.sol
pragma solidity 0.8.10;
import '@openzeppelin/contracts/token/ERC20/IERC20.sol';
interface IOpenSkyOToken is IERC20 {
event Mint(address indexed account, uint256 amount, uint256 index);
event Burn(address indexed account, uint256 amount, uint256 index);
event MintToTreasury(address treasury, uint256 amount, uint256 index);
event Deposit(uint256 amount);
event Withdraw(uint256 amount);
function mint(
address account,
uint256 amount,
uint256 index
) external;
function burn(
address account,
uint256 amount,
uint256 index
) external;
function mintToTreasury(uint256 amount, uint256 index) external;
function deposit(uint256 amount) external;
function withdraw(uint256 amount, address to) external;
function scaledBalanceOf(address account) external view returns (uint256);
function principleBalanceOf(address account) external view returns (uint256);
function scaledTotalSupply() external view returns (uint256);
function principleTotalSupply() external view returns (uint256);
function getScaledUserBalanceAndSupply(address user) external view returns (uint256, uint256);
function claimERC20Rewards(address token) external;
}
文件 16 的 23:IOpenSkyPool.sol
pragma solidity 0.8.10;
import '../libraries/types/DataTypes.sol';
interface IOpenSkyPool {
event Create(
uint256 indexed reserveId,
address indexed underlyingAsset,
address indexed oTokenAddress,
string name,
string symbol,
uint8 decimals
);
event SetTreasuryFactor(uint256 indexed reserveId, uint256 factor);
event SetInterestModelAddress(uint256 indexed reserveId, address interestModelAddress);
event OpenMoneyMarket(uint256 reserveId);
event CloseMoneyMarket(uint256 reserveId);
event Deposit(uint256 indexed reserveId, address indexed onBehalfOf, uint256 amount, uint256 referralCode);
event Withdraw(uint256 indexed reserveId, address indexed onBehalfOf, uint256 amount);
event Borrow(
uint256 indexed reserveId,
address user,
address indexed onBehalfOf,
uint256 indexed loanId
);
event Repay(
uint256 indexed reserveId,
address repayer,
address indexed onBehalfOf,
uint256 indexed loanId,
uint256 repayAmount,
uint256 penalty
);
event Extend(uint256 indexed reserveId, address indexed onBehalfOf, uint256 oldLoanId, uint256 newLoanId);
event StartLiquidation(
uint256 indexed reserveId,
uint256 indexed loanId,
address indexed nftAddress,
uint256 tokenId,
address operator
);
event EndLiquidation(
uint256 indexed reserveId,
uint256 indexed loanId,
address indexed nftAddress,
uint256 tokenId,
address operator,
uint256 repayAmount,
uint256 borrowBalance
);
function create(
address underlyingAsset,
string memory name,
string memory symbol,
uint8 decimals
) external;
function setTreasuryFactor(uint256 reserveId, uint256 factor) external;
function setInterestModelAddress(uint256 reserveId, address interestModelAddress) external;
function openMoneyMarket(uint256 reserveId) external;
function closeMoneyMarket(uint256 reserveId) external;
function deposit(uint256 reserveId, uint256 amount, address onBehalfOf, uint256 referralCode) external;
function withdraw(uint256 reserveId, uint256 amount, address onBehalfOf) external;
function borrow(
uint256 reserveId,
uint256 amount,
uint256 duration,
address nftAddress,
uint256 tokenId,
address onBehalfOf
) external returns (uint256);
function repay(uint256 loanId) external returns (uint256);
function extend(
uint256 loanId,
uint256 amount,
uint256 duration,
address onBehalfOf
) external returns (uint256, uint256);
function startLiquidation(uint256 loanId) external;
function endLiquidation(uint256 loanId, uint256 amount) external;
function getReserveData(uint256 reserveId) external view returns (DataTypes.ReserveData memory);
function getReserveNormalizedIncome(uint256 reserveId) external view returns (uint256);
function getAvailableLiquidity(uint256 reserveId) external view returns (uint256);
function getBorrowLimitByOracle(
uint256 reserveId,
address nftAddress,
uint256 tokenId
) external view returns (uint256);
function getTotalBorrowBalance(uint256 reserveId) external view returns (uint256);
function getTVL(uint256 reserveId) external view returns (uint256);
}
文件 17 的 23:IOpenSkySettings.sol
pragma solidity 0.8.10;
import '../libraries/types/DataTypes.sol';
interface IOpenSkySettings {
event InitPoolAddress(address operator, address address_);
event InitLoanAddress(address operator, address address_);
event InitVaultFactoryAddress(address operator, address address_);
event InitIncentiveControllerAddress(address operator, address address_);
event InitWETHGatewayAddress(address operator, address address_);
event InitPunkGatewayAddress(address operator, address address_);
event InitDaoVaultAddress(address operator, address address_);
event AddToWhitelist(address operator, uint256 reserveId, address nft);
event RemoveFromWhitelist(address operator, uint256 reserveId, address nft);
event SetReserveFactor(address operator, uint256 factor);
event SetPrepaymentFeeFactor(address operator, uint256 factor);
event SetOverdueLoanFeeFactor(address operator, uint256 factor);
event SetMoneyMarketAddress(address operator, address address_);
event SetTreasuryAddress(address operator, address address_);
event SetACLManagerAddress(address operator, address address_);
event SetLoanDescriptorAddress(address operator, address address_);
event SetNftPriceOracleAddress(address operator, address address_);
event SetInterestRateStrategyAddress(address operator, address address_);
event AddLiquidator(address operator, address address_);
event RemoveLiquidator(address operator, address address_);
function poolAddress() external view returns (address);
function loanAddress() external view returns (address);
function vaultFactoryAddress() external view returns (address);
function incentiveControllerAddress() external view returns (address);
function wethGatewayAddress() external view returns (address);
function punkGatewayAddress() external view returns (address);
function inWhitelist(uint256 reserveId, address nft) external view returns (bool);
function getWhitelistDetail(uint256 reserveId, address nft) external view returns (DataTypes.WhitelistInfo memory);
function reserveFactor() external view returns (uint256);
function MAX_RESERVE_FACTOR() external view returns (uint256);
function prepaymentFeeFactor() external view returns (uint256);
function overdueLoanFeeFactor() external view returns (uint256);
function moneyMarketAddress() external view returns (address);
function treasuryAddress() external view returns (address);
function daoVaultAddress() external view returns (address);
function ACLManagerAddress() external view returns (address);
function loanDescriptorAddress() external view returns (address);
function nftPriceOracleAddress() external view returns (address);
function interestRateStrategyAddress() external view returns (address);
function isLiquidator(address liquidator) external view returns (bool);
}
文件 18 的 23:OpenSkyOToken.sol
pragma solidity 0.8.10;
import '@openzeppelin/contracts/token/ERC20/ERC20.sol';
import '@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol';
import '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';
import '@openzeppelin/contracts/token/ERC721/utils/ERC721Holder.sol';
import '@openzeppelin/contracts/token/ERC20/extensions/draft-ERC20Permit.sol';
import '@openzeppelin/contracts/utils/Context.sol';
import './libraries/math/WadRayMath.sol';
import './interfaces/IOpenSkySettings.sol';
import './interfaces/IOpenSkyOToken.sol';
import './interfaces/IOpenSkyPool.sol';
import './interfaces/IOpenSkyIncentivesController.sol';
import './interfaces/IOpenSkyMoneyMarket.sol';
contract OpenSkyOToken is Context, ERC20Permit, ERC20Burnable, ERC721Holder, IOpenSkyOToken {
using WadRayMath for uint256;
using SafeERC20 for IERC20;
IOpenSkySettings public immutable SETTINGS;
address internal immutable _pool;
uint256 internal immutable _reserveId;
address internal immutable _underlyingAsset;
uint8 private _decimals;
modifier onlyPool() {
require(_msgSender() == address(_pool), Errors.ACL_ONLY_POOL_CAN_CALL);
_;
}
constructor(
address pool,
uint256 reserveId,
string memory name,
string memory symbol,
uint8 decimals,
address underlyingAsset,
address settings
) ERC20(name, symbol) ERC20Permit(symbol) {
_decimals = decimals;
_pool = pool;
_reserveId = reserveId;
_underlyingAsset = underlyingAsset;
SETTINGS = IOpenSkySettings(settings);
}
function decimals() public view virtual override returns (uint8) {
return _decimals;
}
function _treasury() internal view returns (address) {
return SETTINGS.daoVaultAddress();
}
function mint(
address account,
uint256 amount,
uint256 index
) external virtual override onlyPool {
uint256 amountScaled = amount.rayDiv(index);
require(amountScaled != 0, Errors.AMOUNT_SCALED_IS_ZERO);
_mint(account, amountScaled);
emit Mint(account, amount, index);
}
function _mint(address account, uint256 amount) internal virtual override {
uint256 previousBalance = super.balanceOf(account);
uint256 previousTotalSupply = super.totalSupply();
super._mint(account, amount);
address incentiveControllerAddress = SETTINGS.incentiveControllerAddress();
if (incentiveControllerAddress != address(0)) {
IOpenSkyIncentivesController(incentiveControllerAddress).handleAction(
account,
previousBalance,
previousTotalSupply
);
}
}
function burn(
address account,
uint256 amount,
uint256 index
) external virtual override onlyPool {
uint256 amountScaled = amount.rayDiv(index);
require(amountScaled != 0, Errors.AMOUNT_SCALED_IS_ZERO);
_burn(account, amountScaled);
emit Burn(account, amount, index);
}
function _burn(address account, uint256 amount) internal virtual override {
uint256 previousBalance = super.balanceOf(account);
uint256 previousTotalSupply = super.totalSupply();
super._burn(account, amount);
address incentiveControllerAddress = SETTINGS.incentiveControllerAddress();
if (incentiveControllerAddress != address(0)) {
IOpenSkyIncentivesController(incentiveControllerAddress).handleAction(
account,
previousBalance,
previousTotalSupply
);
}
}
function _transfer(
address sender,
address recipient,
uint256 amount
) internal override {
uint256 index = IOpenSkyPool(_pool).getReserveNormalizedIncome(_reserveId);
uint256 amountScaled = amount.rayDiv(index);
require(amountScaled != 0, Errors.AMOUNT_SCALED_IS_ZERO);
require(amountScaled <= type(uint128).max, Errors.AMOUNT_TRANSFER_OVERFLOW);
uint256 previousSenderBalance = super.balanceOf(sender);
uint256 previousRecipientBalance = super.balanceOf(recipient);
super._transfer(sender, recipient, amountScaled);
address incentiveControllerAddress = SETTINGS.incentiveControllerAddress();
if (incentiveControllerAddress != address(0)) {
uint256 currentTotalSupply = super.totalSupply();
IOpenSkyIncentivesController(incentiveControllerAddress).handleAction(
sender,
previousSenderBalance,
currentTotalSupply
);
if (sender != recipient) {
IOpenSkyIncentivesController(incentiveControllerAddress).handleAction(
recipient,
previousRecipientBalance,
currentTotalSupply
);
}
}
}
function mintToTreasury(uint256 amount, uint256 index) external override onlyPool {
if (amount == 0) {
return;
}
_mint(_treasury(), amount.rayDiv(index));
emit MintToTreasury(_treasury(), amount, index);
}
function _beforeTokenTransfer(
address from,
address to,
uint256 amount
) internal virtual override(ERC20) {
super._beforeTokenTransfer(from, to, amount);
}
event Received(address, uint256);
receive() external payable {
emit Received(msg.sender, msg.value);
}
function deposit(uint256 amount) external override onlyPool {
DataTypes.ReserveData memory reserve = IOpenSkyPool(_pool).getReserveData(_reserveId);
if (reserve.isMoneyMarketOn) {
(bool success, ) = address(reserve.moneyMarketAddress).delegatecall(
abi.encodeWithSignature('depositCall(address,uint256)', _underlyingAsset, amount)
);
require(success, Errors.MONEY_MARKET_DELEGATE_CALL_ERROR);
}
emit Deposit(amount);
}
function withdraw(uint256 amount, address to) external override onlyPool {
DataTypes.ReserveData memory reserve = IOpenSkyPool(_pool).getReserveData(_reserveId);
if (reserve.isMoneyMarketOn) {
(bool success, ) = address(reserve.moneyMarketAddress).delegatecall(
abi.encodeWithSignature('withdrawCall(address,uint256,address)', _underlyingAsset, amount, to)
);
require(success, Errors.MONEY_MARKET_DELEGATE_CALL_ERROR);
} else {
IERC20(_underlyingAsset).safeTransfer(to, amount);
}
emit Withdraw(amount);
}
function balanceOf(address account) public view override(ERC20, IERC20) returns (uint256) {
uint256 index = IOpenSkyPool(_pool).getReserveNormalizedIncome(_reserveId);
return super.balanceOf(account).rayMul(index);
}
function scaledBalanceOf(address account) external view override returns (uint256) {
return super.balanceOf(account);
}
function principleBalanceOf(address account) external view override returns (uint256) {
uint256 currentBalanceScaled = super.balanceOf(account);
uint256 lastSupplyIndex = IOpenSkyPool(_pool).getReserveData(_reserveId).lastSupplyIndex;
return currentBalanceScaled.rayMul(lastSupplyIndex);
}
function totalSupply() public view override(ERC20, IERC20) returns (uint256) {
uint256 currentSupplyScaled = super.totalSupply();
if (currentSupplyScaled == 0) {
return 0;
}
return currentSupplyScaled.rayMul(IOpenSkyPool(_pool).getReserveNormalizedIncome(_reserveId));
}
function scaledTotalSupply() external view virtual override returns (uint256) {
return super.totalSupply();
}
function principleTotalSupply() external view virtual override returns (uint256) {
uint256 currentSupplyScaled = super.totalSupply();
uint256 lastSupplyIndex = IOpenSkyPool(_pool).getReserveData(_reserveId).lastSupplyIndex;
return currentSupplyScaled.rayMul(lastSupplyIndex);
}
function getScaledUserBalanceAndSupply(address user) external view override returns (uint256, uint256) {
return (super.balanceOf(user), super.totalSupply());
}
function claimERC20Rewards(address token) external override onlyPool {
DataTypes.ReserveData memory reserve = IOpenSkyPool(_pool).getReserveData(_reserveId);
require(
token != IOpenSkyMoneyMarket(reserve.moneyMarketAddress).getMoneyMarketToken(_underlyingAsset) &&
token != _underlyingAsset,
Errors.RESERVE_TOKEN_CAN_NOT_BE_CLAIMED
);
IERC20(token).safeTransfer(_treasury(), IERC20(token).balanceOf(address(this)));
}
}
文件 19 的 23: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");
}
}
}
文件 20 的 23:WadRayMath.sol
pragma solidity 0.8.10;
import {Errors} from '../helpers/Errors.sol';
library WadRayMath {
uint256 internal constant WAD = 1e18;
uint256 internal constant halfWAD = WAD / 2;
uint256 internal constant RAY = 1e27;
uint256 internal constant halfRAY = RAY / 2;
uint256 internal constant WAD_RAY_RATIO = 1e9;
function ray() internal pure returns (uint256) {
return RAY;
}
function wad() internal pure returns (uint256) {
return WAD;
}
function halfRay() internal pure returns (uint256) {
return halfRAY;
}
function halfWad() internal pure returns (uint256) {
return halfWAD;
}
function wadMul(uint256 a, uint256 b) internal pure returns (uint256) {
if (a == 0 || b == 0) {
return 0;
}
require(a <= (type(uint256).max - halfWAD) / b, Errors.MATH_MULTIPLICATION_OVERFLOW);
return (a * b + halfWAD) / WAD;
}
function wadDiv(uint256 a, uint256 b) internal pure returns (uint256) {
require(b != 0, Errors.MATH_DIVISION_BY_ZERO);
uint256 halfB = b / 2;
require(a <= (type(uint256).max - halfB) / WAD, Errors.MATH_MULTIPLICATION_OVERFLOW);
return (a * WAD + halfB) / b;
}
function rayMul(uint256 a, uint256 b) internal pure returns (uint256) {
if (a == 0 || b == 0) {
return 0;
}
require(a <= (type(uint256).max - halfRAY) / b, Errors.MATH_MULTIPLICATION_OVERFLOW);
return (a * b + halfRAY) / RAY;
}
function rayMulTruncate(uint256 a, uint256 b) internal pure returns (uint256) {
if (a == 0 || b == 0) {
return 0;
}
return (a * b) / RAY;
}
function rayDiv(uint256 a, uint256 b) internal pure returns (uint256) {
require(b != 0, Errors.MATH_DIVISION_BY_ZERO);
uint256 halfB = b / 2;
require(a <= (type(uint256).max - halfB) / RAY, Errors.MATH_MULTIPLICATION_OVERFLOW);
return (a * RAY + halfB) / b;
}
function rayDivTruncate(uint256 a, uint256 b) internal pure returns (uint256) {
require(b != 0, Errors.MATH_DIVISION_BY_ZERO);
return (a * RAY) / b;
}
function rayToWad(uint256 a) internal pure returns (uint256) {
uint256 halfRatio = WAD_RAY_RATIO / 2;
uint256 result = halfRatio + a;
require(result >= halfRatio, Errors.MATH_ADDITION_OVERFLOW);
return result / WAD_RAY_RATIO;
}
function wadToRay(uint256 a) internal pure returns (uint256) {
uint256 result = a * WAD_RAY_RATIO;
require(result / WAD_RAY_RATIO == a, Errors.MATH_MULTIPLICATION_OVERFLOW);
return result;
}
}
文件 21 的 23:draft-EIP712.sol
pragma solidity ^0.8.0;
import "./ECDSA.sol";
abstract contract EIP712 {
bytes32 private immutable _CACHED_DOMAIN_SEPARATOR;
uint256 private immutable _CACHED_CHAIN_ID;
bytes32 private immutable _HASHED_NAME;
bytes32 private immutable _HASHED_VERSION;
bytes32 private immutable _TYPE_HASH;
constructor(string memory name, string memory version) {
bytes32 hashedName = keccak256(bytes(name));
bytes32 hashedVersion = keccak256(bytes(version));
bytes32 typeHash = keccak256(
"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"
);
_HASHED_NAME = hashedName;
_HASHED_VERSION = hashedVersion;
_CACHED_CHAIN_ID = block.chainid;
_CACHED_DOMAIN_SEPARATOR = _buildDomainSeparator(typeHash, hashedName, hashedVersion);
_TYPE_HASH = typeHash;
}
function _domainSeparatorV4() internal view returns (bytes32) {
if (block.chainid == _CACHED_CHAIN_ID) {
return _CACHED_DOMAIN_SEPARATOR;
} else {
return _buildDomainSeparator(_TYPE_HASH, _HASHED_NAME, _HASHED_VERSION);
}
}
function _buildDomainSeparator(
bytes32 typeHash,
bytes32 nameHash,
bytes32 versionHash
) private view returns (bytes32) {
return keccak256(abi.encode(typeHash, nameHash, versionHash, block.chainid, address(this)));
}
function _hashTypedDataV4(bytes32 structHash) internal view virtual returns (bytes32) {
return ECDSA.toTypedDataHash(_domainSeparatorV4(), structHash);
}
}
文件 22 的 23:draft-ERC20Permit.sol
pragma solidity ^0.8.0;
import "./draft-IERC20Permit.sol";
import "../ERC20.sol";
import "../../../utils/cryptography/draft-EIP712.sol";
import "../../../utils/cryptography/ECDSA.sol";
import "../../../utils/Counters.sol";
abstract contract ERC20Permit is ERC20, IERC20Permit, EIP712 {
using Counters for Counters.Counter;
mapping(address => Counters.Counter) private _nonces;
bytes32 private immutable _PERMIT_TYPEHASH =
keccak256("Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)");
constructor(string memory name) EIP712(name, "1") {}
function permit(
address owner,
address spender,
uint256 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) public virtual override {
require(block.timestamp <= deadline, "ERC20Permit: expired deadline");
bytes32 structHash = keccak256(abi.encode(_PERMIT_TYPEHASH, owner, spender, value, _useNonce(owner), deadline));
bytes32 hash = _hashTypedDataV4(structHash);
address signer = ECDSA.recover(hash, v, r, s);
require(signer == owner, "ERC20Permit: invalid signature");
_approve(owner, spender, value);
}
function nonces(address owner) public view virtual override returns (uint256) {
return _nonces[owner].current();
}
function DOMAIN_SEPARATOR() external view override returns (bytes32) {
return _domainSeparatorV4();
}
function _useNonce(address owner) internal virtual returns (uint256 current) {
Counters.Counter storage nonce = _nonces[owner];
current = nonce.current();
nonce.increment();
}
}
文件 23 的 23:draft-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);
}
{
"compilationTarget": {
"contracts/OpenSkyOToken.sol": "OpenSkyOToken"
},
"evmVersion": "london",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs",
"useLiteralContent": true
},
"optimizer": {
"enabled": true,
"runs": 200
},
"remappings": []
}
[{"inputs":[{"internalType":"address","name":"pool","type":"address"},{"internalType":"uint256","name":"reserveId","type":"uint256"},{"internalType":"string","name":"name","type":"string"},{"internalType":"string","name":"symbol","type":"string"},{"internalType":"uint8","name":"decimals","type":"uint8"},{"internalType":"address","name":"underlyingAsset","type":"address"},{"internalType":"address","name":"settings","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":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"index","type":"uint256"}],"name":"Burn","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Deposit","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"index","type":"uint256"}],"name":"Mint","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"treasury","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"index","type":"uint256"}],"name":"MintToTreasury","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"","type":"address"},{"indexed":false,"internalType":"uint256","name":"","type":"uint256"}],"name":"Received","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"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Withdraw","type":"event"},{"inputs":[],"name":"DOMAIN_SEPARATOR","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"SETTINGS","outputs":[{"internalType":"contract IOpenSkySettings","name":"","type":"address"}],"stateMutability":"view","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":"uint256","name":"amount","type":"uint256"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"burnFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"claimERC20Rewards","outputs":[],"stateMutability":"nonpayable","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":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"deposit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"getScaledUserBalanceAndSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"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":"address","name":"account","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"mint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"mintToTreasury","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"nonces","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"onERC721Received","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"permit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"principleBalanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"principleTotalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"scaledBalanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"scaledTotalSupply","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":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"address","name":"to","type":"address"}],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]