编译器
0.8.17+commit.8df45f5f
文件 1 的 54:AccessControlLibV1.sol
pragma solidity ^0.8.0;
import "openzeppelin-solidity/contracts/token/ERC20/IERC20.sol";
import "openzeppelin-solidity/contracts/access/IAccessControl.sol";
import "./ProtoUtilV1.sol";
library AccessControlLibV1 {
using ProtoUtilV1 for IStore;
using StoreKeyUtil for IStore;
bytes32 public constant NS_ROLES_ADMIN = 0x00;
bytes32 public constant NS_ROLES_COVER_MANAGER = "role:cover:manager";
bytes32 public constant NS_ROLES_LIQUIDITY_MANAGER = "role:liquidity:manager";
bytes32 public constant NS_ROLES_GOVERNANCE_AGENT = "role:governance:agent";
bytes32 public constant NS_ROLES_GOVERNANCE_ADMIN = "role:governance:admin";
bytes32 public constant NS_ROLES_UPGRADE_AGENT = "role:upgrade:agent";
bytes32 public constant NS_ROLES_RECOVERY_AGENT = "role:recovery:agent";
bytes32 public constant NS_ROLES_PAUSE_AGENT = "role:pause:agent";
bytes32 public constant NS_ROLES_UNPAUSE_AGENT = "role:unpause:agent";
function mustBeAdmin(IStore s) external view {
_mustHaveAccess(s, NS_ROLES_ADMIN, msg.sender);
}
function mustBeCoverManager(IStore s) external view {
_mustHaveAccess(s, NS_ROLES_COVER_MANAGER, msg.sender);
}
function mustBeLiquidityManager(IStore s) external view {
_mustHaveAccess(s, NS_ROLES_LIQUIDITY_MANAGER, msg.sender);
}
function mustBeGovernanceAgent(IStore s) external view {
_mustHaveAccess(s, NS_ROLES_GOVERNANCE_AGENT, msg.sender);
}
function mustBeGovernanceAdmin(IStore s) external view {
_mustHaveAccess(s, NS_ROLES_GOVERNANCE_ADMIN, msg.sender);
}
function mustBeUpgradeAgent(IStore s) external view {
_mustHaveAccess(s, NS_ROLES_UPGRADE_AGENT, msg.sender);
}
function mustBeRecoveryAgent(IStore s) external view {
_mustHaveAccess(s, NS_ROLES_RECOVERY_AGENT, msg.sender);
}
function mustBePauseAgent(IStore s) external view {
_mustHaveAccess(s, NS_ROLES_PAUSE_AGENT, msg.sender);
}
function mustBeUnpauseAgent(IStore s) external view {
_mustHaveAccess(s, NS_ROLES_UNPAUSE_AGENT, msg.sender);
}
function callerMustBeAdmin(IStore s, address caller) external view {
_mustHaveAccess(s, NS_ROLES_ADMIN, caller);
}
function callerMustBeCoverManager(IStore s, address caller) external view {
_mustHaveAccess(s, NS_ROLES_COVER_MANAGER, caller);
}
function callerMustBeLiquidityManager(IStore s, address caller) external view {
_mustHaveAccess(s, NS_ROLES_LIQUIDITY_MANAGER, caller);
}
function callerMustBeGovernanceAgent(IStore s, address caller) external view {
_mustHaveAccess(s, NS_ROLES_GOVERNANCE_AGENT, caller);
}
function callerMustBeGovernanceAdmin(IStore s, address caller) external view {
_mustHaveAccess(s, NS_ROLES_GOVERNANCE_ADMIN, caller);
}
function callerMustBeUpgradeAgent(IStore s, address caller) public view {
_mustHaveAccess(s, NS_ROLES_UPGRADE_AGENT, caller);
}
function callerMustBeRecoveryAgent(IStore s, address caller) external view {
_mustHaveAccess(s, NS_ROLES_RECOVERY_AGENT, caller);
}
function callerMustBePauseAgent(IStore s, address caller) external view {
_mustHaveAccess(s, NS_ROLES_PAUSE_AGENT, caller);
}
function callerMustBeUnpauseAgent(IStore s, address caller) external view {
_mustHaveAccess(s, NS_ROLES_UNPAUSE_AGENT, caller);
}
function _mustHaveAccess(
IStore s,
bytes32 role,
address caller
) private view {
require(hasAccessInternal(s, role, caller), "Forbidden");
}
function hasAccessInternal(
IStore s,
bytes32 role,
address user
) public view returns (bool) {
address protocol = s.getProtocolAddressInternal();
if (protocol == address(0)) {
return false;
}
return IAccessControl(protocol).hasRole(role, user);
}
function addContractInternal(
IStore s,
bytes32 namespace,
bytes32 key,
address contractAddress
) external {
callerMustBeUpgradeAgent(s, address(this));
_addContract(s, namespace, key, contractAddress);
}
function _addContract(
IStore s,
bytes32 namespace,
bytes32 key,
address contractAddress
) private {
if (key > 0) {
s.setAddressByKeys(ProtoUtilV1.NS_CONTRACTS, namespace, key, contractAddress);
} else {
s.setAddressByKeys(ProtoUtilV1.NS_CONTRACTS, namespace, contractAddress);
}
_addMember(s, contractAddress);
}
function _deleteContract(
IStore s,
bytes32 namespace,
bytes32 key,
address contractAddress
) private {
if (key > 0) {
s.deleteAddressByKeys(ProtoUtilV1.NS_CONTRACTS, namespace, key);
} else {
s.deleteAddressByKeys(ProtoUtilV1.NS_CONTRACTS, namespace);
}
_removeMember(s, contractAddress);
}
function upgradeContractInternal(
IStore s,
bytes32 namespace,
bytes32 key,
address previous,
address current
) external {
callerMustBeUpgradeAgent(s, address(this));
bool isMember = s.isProtocolMemberInternal(previous);
require(isMember, "Not a protocol member");
_deleteContract(s, namespace, key, previous);
_addContract(s, namespace, key, current);
}
function addMemberInternal(IStore s, address member) external {
callerMustBeUpgradeAgent(s, address(this));
_addMember(s, member);
}
function removeMemberInternal(IStore s, address member) external {
callerMustBeUpgradeAgent(s, address(this));
_removeMember(s, member);
}
function _addMember(IStore s, address member) private {
require(s.getBoolByKeys(ProtoUtilV1.NS_MEMBERS, member) == false, "Already exists");
s.setBoolByKeys(ProtoUtilV1.NS_MEMBERS, member, true);
}
function _removeMember(IStore s, address member) private {
s.deleteBoolByKeys(ProtoUtilV1.NS_MEMBERS, member);
}
}
文件 2 的 54: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);
}
}
}
}
文件 3 的 54:BaseLibV1.sol
pragma solidity ^0.8.0;
import "openzeppelin-solidity/contracts/token/ERC20/IERC20.sol";
import "openzeppelin-solidity/contracts/token/ERC20/utils/SafeERC20.sol";
import "../interfaces/IProtocol.sol";
import "../interfaces/IPausable.sol";
library BaseLibV1 {
using SafeERC20 for IERC20;
function recoverEtherInternal(address sendTo) external {
(bool success, ) = payable(sendTo).call{value: address(this).balance}("");
require(success, "Recipient may have reverted");
}
function recoverTokenInternal(address token, address sendTo) external {
IERC20 erc20 = IERC20(token);
uint256 balance = erc20.balanceOf(address(this));
if (balance > 0) {
erc20.safeTransfer(sendTo, balance);
}
}
}
文件 4 的 54:BokkyPooBahsDateTimeLibrary.sol
pragma solidity ^0.8.0;
library BokkyPooBahsDateTimeLibrary {
uint256 internal constant SECONDS_PER_DAY = 24 * 60 * 60;
uint256 internal constant SECONDS_PER_HOUR = 60 * 60;
uint256 internal constant SECONDS_PER_MINUTE = 60;
int256 internal constant OFFSET19700101 = 2440588;
uint256 internal constant DOW_MON = 1;
uint256 internal constant DOW_TUE = 2;
uint256 internal constant DOW_WED = 3;
uint256 internal constant DOW_THU = 4;
uint256 internal constant DOW_FRI = 5;
uint256 internal constant DOW_SAT = 6;
uint256 internal constant DOW_SUN = 7;
function _daysFromDate(
uint256 year,
uint256 month,
uint256 day
) internal pure returns (uint256 _days) {
require(year >= 1970);
int256 _year = int256(year);
int256 _month = int256(month);
int256 _day = int256(day);
int256 __days = _day -
32075 +
(1461 * (_year + 4800 + (_month - 14) / 12)) /
4 +
(367 * (_month - 2 - ((_month - 14) / 12) * 12)) /
12 -
(3 * ((_year + 4900 + (_month - 14) / 12) / 100)) /
4 -
OFFSET19700101;
_days = uint256(__days);
}
function _daysToDate(uint256 _days)
internal
pure
returns (
uint256 year,
uint256 month,
uint256 day
)
{
int256 __days = int256(_days);
int256 L = __days + 68569 + OFFSET19700101;
int256 N = (4 * L) / 146097;
L = L - (146097 * N + 3) / 4;
int256 _year = (4000 * (L + 1)) / 1461001;
L = L - (1461 * _year) / 4 + 31;
int256 _month = (80 * L) / 2447;
int256 _day = L - (2447 * _month) / 80;
L = _month / 11;
_month = _month + 2 - 12 * L;
_year = 100 * (N - 49) + _year + L;
year = uint256(_year);
month = uint256(_month);
day = uint256(_day);
}
function timestampFromDate(
uint256 year,
uint256 month,
uint256 day
) internal pure returns (uint256 timestamp) {
timestamp = _daysFromDate(year, month, day) * SECONDS_PER_DAY;
}
function timestampFromDateTime(
uint256 year,
uint256 month,
uint256 day,
uint256 hour,
uint256 minute,
uint256 second
) internal pure returns (uint256 timestamp) {
timestamp = _daysFromDate(year, month, day) * SECONDS_PER_DAY + hour * SECONDS_PER_HOUR + minute * SECONDS_PER_MINUTE + second;
}
function timestampToDate(uint256 timestamp)
internal
pure
returns (
uint256 year,
uint256 month,
uint256 day
)
{
(year, month, day) = _daysToDate(timestamp / SECONDS_PER_DAY);
}
function timestampToDateTime(uint256 timestamp)
internal
pure
returns (
uint256 year,
uint256 month,
uint256 day,
uint256 hour,
uint256 minute,
uint256 second
)
{
(year, month, day) = _daysToDate(timestamp / SECONDS_PER_DAY);
uint256 secs = timestamp % SECONDS_PER_DAY;
hour = secs / SECONDS_PER_HOUR;
secs = secs % SECONDS_PER_HOUR;
minute = secs / SECONDS_PER_MINUTE;
second = secs % SECONDS_PER_MINUTE;
}
function isValidDate(
uint256 year,
uint256 month,
uint256 day
) internal pure returns (bool valid) {
if (year >= 1970 && month > 0 && month <= 12) {
uint256 daysInMonth = _getDaysInMonth(year, month);
if (day > 0 && day <= daysInMonth) {
valid = true;
}
}
}
function isValidDateTime(
uint256 year,
uint256 month,
uint256 day,
uint256 hour,
uint256 minute,
uint256 second
) internal pure returns (bool valid) {
if (isValidDate(year, month, day)) {
if (hour < 24 && minute < 60 && second < 60) {
valid = true;
}
}
}
function isLeapYear(uint256 timestamp) internal pure returns (bool leapYear) {
(uint256 year, , ) = _daysToDate(timestamp / SECONDS_PER_DAY);
leapYear = _isLeapYear(year);
}
function _isLeapYear(uint256 year) internal pure returns (bool leapYear) {
leapYear = ((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0);
}
function isWeekDay(uint256 timestamp) internal pure returns (bool weekDay) {
weekDay = getDayOfWeek(timestamp) <= DOW_FRI;
}
function isWeekEnd(uint256 timestamp) internal pure returns (bool weekEnd) {
weekEnd = getDayOfWeek(timestamp) >= DOW_SAT;
}
function getDaysInMonth(uint256 timestamp) internal pure returns (uint256 daysInMonth) {
(uint256 year, uint256 month, ) = _daysToDate(timestamp / SECONDS_PER_DAY);
daysInMonth = _getDaysInMonth(year, month);
}
function _getDaysInMonth(uint256 year, uint256 month) internal pure returns (uint256 daysInMonth) {
if (month == 1 || month == 3 || month == 5 || month == 7 || month == 8 || month == 10 || month == 12) {
daysInMonth = 31;
} else if (month != 2) {
daysInMonth = 30;
} else {
daysInMonth = _isLeapYear(year) ? 29 : 28;
}
}
function getDayOfWeek(uint256 timestamp) internal pure returns (uint256 dayOfWeek) {
uint256 _days = timestamp / SECONDS_PER_DAY;
dayOfWeek = ((_days + 3) % 7) + 1;
}
function getYear(uint256 timestamp) internal pure returns (uint256 year) {
(year, , ) = _daysToDate(timestamp / SECONDS_PER_DAY);
}
function getMonth(uint256 timestamp) internal pure returns (uint256 month) {
(, month, ) = _daysToDate(timestamp / SECONDS_PER_DAY);
}
function getDay(uint256 timestamp) internal pure returns (uint256 day) {
(, , day) = _daysToDate(timestamp / SECONDS_PER_DAY);
}
function getHour(uint256 timestamp) internal pure returns (uint256 hour) {
uint256 secs = timestamp % SECONDS_PER_DAY;
hour = secs / SECONDS_PER_HOUR;
}
function getMinute(uint256 timestamp) internal pure returns (uint256 minute) {
uint256 secs = timestamp % SECONDS_PER_HOUR;
minute = secs / SECONDS_PER_MINUTE;
}
function getSecond(uint256 timestamp) internal pure returns (uint256 second) {
second = timestamp % SECONDS_PER_MINUTE;
}
function addYears(uint256 timestamp, uint256 _years) internal pure returns (uint256 newTimestamp) {
(uint256 year, uint256 month, uint256 day) = _daysToDate(timestamp / SECONDS_PER_DAY);
year += _years;
uint256 daysInMonth = _getDaysInMonth(year, month);
if (day > daysInMonth) {
day = daysInMonth;
}
newTimestamp = _daysFromDate(year, month, day) * SECONDS_PER_DAY + (timestamp % SECONDS_PER_DAY);
require(newTimestamp >= timestamp);
}
function addMonths(uint256 timestamp, uint256 _months) internal pure returns (uint256 newTimestamp) {
(uint256 year, uint256 month, uint256 day) = _daysToDate(timestamp / SECONDS_PER_DAY);
month += _months;
year += (month - 1) / 12;
month = ((month - 1) % 12) + 1;
uint256 daysInMonth = _getDaysInMonth(year, month);
if (day > daysInMonth) {
day = daysInMonth;
}
newTimestamp = _daysFromDate(year, month, day) * SECONDS_PER_DAY + (timestamp % SECONDS_PER_DAY);
require(newTimestamp >= timestamp);
}
function addDays(uint256 timestamp, uint256 _days) internal pure returns (uint256 newTimestamp) {
newTimestamp = timestamp + _days * SECONDS_PER_DAY;
require(newTimestamp >= timestamp);
}
function addHours(uint256 timestamp, uint256 _hours) internal pure returns (uint256 newTimestamp) {
newTimestamp = timestamp + _hours * SECONDS_PER_HOUR;
require(newTimestamp >= timestamp);
}
function addMinutes(uint256 timestamp, uint256 _minutes) internal pure returns (uint256 newTimestamp) {
newTimestamp = timestamp + _minutes * SECONDS_PER_MINUTE;
require(newTimestamp >= timestamp);
}
function addSeconds(uint256 timestamp, uint256 _seconds) internal pure returns (uint256 newTimestamp) {
newTimestamp = timestamp + _seconds;
require(newTimestamp >= timestamp);
}
function subYears(uint256 timestamp, uint256 _years) internal pure returns (uint256 newTimestamp) {
(uint256 year, uint256 month, uint256 day) = _daysToDate(timestamp / SECONDS_PER_DAY);
year -= _years;
uint256 daysInMonth = _getDaysInMonth(year, month);
if (day > daysInMonth) {
day = daysInMonth;
}
newTimestamp = _daysFromDate(year, month, day) * SECONDS_PER_DAY + (timestamp % SECONDS_PER_DAY);
require(newTimestamp <= timestamp);
}
function subMonths(uint256 timestamp, uint256 _months) internal pure returns (uint256 newTimestamp) {
(uint256 year, uint256 month, uint256 day) = _daysToDate(timestamp / SECONDS_PER_DAY);
uint256 yearMonth = year * 12 + (month - 1) - _months;
year = yearMonth / 12;
month = (yearMonth % 12) + 1;
uint256 daysInMonth = _getDaysInMonth(year, month);
if (day > daysInMonth) {
day = daysInMonth;
}
newTimestamp = _daysFromDate(year, month, day) * SECONDS_PER_DAY + (timestamp % SECONDS_PER_DAY);
require(newTimestamp <= timestamp);
}
function subDays(uint256 timestamp, uint256 _days) internal pure returns (uint256 newTimestamp) {
newTimestamp = timestamp - _days * SECONDS_PER_DAY;
require(newTimestamp <= timestamp);
}
function subHours(uint256 timestamp, uint256 _hours) internal pure returns (uint256 newTimestamp) {
newTimestamp = timestamp - _hours * SECONDS_PER_HOUR;
require(newTimestamp <= timestamp);
}
function subMinutes(uint256 timestamp, uint256 _minutes) internal pure returns (uint256 newTimestamp) {
newTimestamp = timestamp - _minutes * SECONDS_PER_MINUTE;
require(newTimestamp <= timestamp);
}
function subSeconds(uint256 timestamp, uint256 _seconds) internal pure returns (uint256 newTimestamp) {
newTimestamp = timestamp - _seconds;
require(newTimestamp <= timestamp);
}
function diffYears(uint256 fromTimestamp, uint256 toTimestamp) internal pure returns (uint256 _years) {
require(fromTimestamp <= toTimestamp);
(uint256 fromYear, , ) = _daysToDate(fromTimestamp / SECONDS_PER_DAY);
(uint256 toYear, , ) = _daysToDate(toTimestamp / SECONDS_PER_DAY);
_years = toYear - fromYear;
}
function diffMonths(uint256 fromTimestamp, uint256 toTimestamp) internal pure returns (uint256 _months) {
require(fromTimestamp <= toTimestamp);
(uint256 fromYear, uint256 fromMonth, ) = _daysToDate(fromTimestamp / SECONDS_PER_DAY);
(uint256 toYear, uint256 toMonth, ) = _daysToDate(toTimestamp / SECONDS_PER_DAY);
_months = toYear * 12 + toMonth - fromYear * 12 - fromMonth;
}
function diffDays(uint256 fromTimestamp, uint256 toTimestamp) internal pure returns (uint256 _days) {
require(fromTimestamp <= toTimestamp);
_days = (toTimestamp - fromTimestamp) / SECONDS_PER_DAY;
}
function diffHours(uint256 fromTimestamp, uint256 toTimestamp) internal pure returns (uint256 _hours) {
require(fromTimestamp <= toTimestamp);
_hours = (toTimestamp - fromTimestamp) / SECONDS_PER_HOUR;
}
function diffMinutes(uint256 fromTimestamp, uint256 toTimestamp) internal pure returns (uint256 _minutes) {
require(fromTimestamp <= toTimestamp);
_minutes = (toTimestamp - fromTimestamp) / SECONDS_PER_MINUTE;
}
function diffSeconds(uint256 fromTimestamp, uint256 toTimestamp) internal pure returns (uint256 _seconds) {
require(fromTimestamp <= toTimestamp);
_seconds = toTimestamp - fromTimestamp;
}
}
文件 5 的 54: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;
}
}
文件 6 的 54:CoverUtilV1.sol
pragma solidity ^0.8.0;
import "openzeppelin-solidity/contracts/token/ERC20/IERC20.sol";
import "../dependencies/BokkyPooBahsDateTimeLibrary.sol";
import "../interfaces/IStore.sol";
import "../interfaces/ICxToken.sol";
import "../interfaces/IERC20Detailed.sol";
import "./StrategyLibV1.sol";
library CoverUtilV1 {
using ProtoUtilV1 for IStore;
using StoreKeyUtil for IStore;
using StrategyLibV1 for IStore;
uint256 public constant REASSURANCE_WEIGHT_FALLBACK_VALUE = 8000;
uint256 public constant COVER_LAG_FALLBACK_VALUE = 1 days;
enum ProductStatus {
Normal,
Stopped,
IncidentHappened,
FalseReporting,
Claimable
}
function getCoverOwnerInternal(IStore s, bytes32 coverKey) external view returns (address) {
return s.getAddressByKeys(ProtoUtilV1.NS_COVER_OWNER, coverKey);
}
function getCoverCreationFeeInfoInternal(IStore s)
external
view
returns (
uint256 fee,
uint256 minCoverCreationStake,
uint256 minStakeToAddLiquidity
)
{
fee = s.getUintByKey(ProtoUtilV1.NS_COVER_CREATION_FEE);
minCoverCreationStake = getMinCoverCreationStakeInternal(s);
minStakeToAddLiquidity = getMinStakeToAddLiquidityInternal(s);
}
function getMinCoverCreationStakeInternal(IStore s) public view returns (uint256) {
return s.getUintByKey(ProtoUtilV1.NS_COVER_CREATION_MIN_STAKE);
}
function getCoverCreationDateInternal(IStore s, bytes32 coverKey) external view returns (uint256) {
return s.getUintByKeys(ProtoUtilV1.NS_COVER_CREATION_DATE, coverKey);
}
function getMinStakeToAddLiquidityInternal(IStore s) public view returns (uint256) {
return s.getUintByKey(ProtoUtilV1.NS_COVER_LIQUIDITY_MIN_STAKE);
}
function getClaimPeriodInternal(IStore s, bytes32 coverKey) external view returns (uint256) {
uint256 fromKey = s.getUintByKeys(ProtoUtilV1.NS_CLAIM_PERIOD, coverKey);
uint256 fallbackValue = s.getUintByKey(ProtoUtilV1.NS_CLAIM_PERIOD);
return fromKey > 0 ? fromKey : fallbackValue;
}
function getCoverPoolSummaryInternal(
IStore s,
bytes32 coverKey,
bytes32 productKey
) external view returns (IPolicy.CoverPoolSummaryType memory summary) {
uint256 precision = s.getStablecoinPrecisionInternal();
summary.totalAmountInPool = s.getStablecoinOwnedByVaultInternal(coverKey);
summary.totalCommitment = getActiveLiquidityUnderProtectionInternal(s, coverKey, productKey, precision);
summary.reassuranceAmount = getReassuranceAmountInternal(s, coverKey);
summary.reassurancePoolWeight = getReassuranceWeightInternal(s, coverKey);
summary.productCount = s.countBytes32ArrayByKeys(ProtoUtilV1.NS_COVER_PRODUCT, coverKey);
summary.leverage = s.getUintByKeys(ProtoUtilV1.NS_COVER_LEVERAGE_FACTOR, coverKey);
summary.productCapitalEfficiency = s.getUintByKeys(ProtoUtilV1.NS_COVER_PRODUCT_EFFICIENCY, coverKey, productKey);
}
function getReassuranceWeightInternal(IStore s, bytes32 coverKey) public view returns (uint256) {
uint256 setForTheCoverPool = s.getUintByKey(getReassuranceWeightKeyInternal(coverKey));
if (setForTheCoverPool > 0) {
return setForTheCoverPool;
}
uint256 setGlobally = s.getUintByKey(getReassuranceWeightKeyInternal(0));
if (setGlobally > 0) {
return setGlobally;
}
return REASSURANCE_WEIGHT_FALLBACK_VALUE;
}
function getReassuranceAmountInternal(IStore s, bytes32 coverKey) public view returns (uint256) {
return s.getUintByKey(getReassuranceKeyInternal(coverKey));
}
function getReassuranceRateInternal(IStore s, bytes32 coverKey) external view returns (uint256) {
uint256 rate = s.getUintByKey(getReassuranceRateKeyInternal(coverKey));
if (rate > 0) {
return rate;
}
return 2500;
}
function getReassuranceKeyInternal(bytes32 coverKey) public pure returns (bytes32) {
return keccak256(abi.encodePacked(ProtoUtilV1.NS_COVER_REASSURANCE, coverKey));
}
function getReassuranceRateKeyInternal(bytes32 coverKey) public pure returns (bytes32) {
return keccak256(abi.encodePacked(ProtoUtilV1.NS_COVER_REASSURANCE_RATE, coverKey));
}
function getReassuranceWeightKeyInternal(bytes32 coverKey) public pure returns (bytes32) {
return keccak256(abi.encodePacked(ProtoUtilV1.NS_COVER_REASSURANCE_WEIGHT, coverKey));
}
function isCoverNormalInternal(IStore s, bytes32 coverKey) external view returns (bool) {
uint256 incidentDate;
bool supportsProducts = supportsProductsInternal(s, coverKey);
if (supportsProducts == false) {
incidentDate = getActiveIncidentDateInternal(s, coverKey, ProtoUtilV1.PRODUCT_KEY_INTENTIONALLY_EMPTY);
return getProductStatusOfInternal(s, coverKey, ProtoUtilV1.PRODUCT_KEY_INTENTIONALLY_EMPTY, incidentDate) == ProductStatus.Normal;
}
bytes32[] memory products = _getProducts(s, coverKey);
for (uint256 i = 0; i < products.length; i++) {
incidentDate = getActiveIncidentDateInternal(s, coverKey, products[i]);
bool isNormal = getProductStatusOfInternal(s, coverKey, products[i], incidentDate) == ProductStatus.Normal;
if (!isNormal) {
return false;
}
}
return true;
}
function getProductStatusInternal(
IStore s,
bytes32 coverKey,
bytes32 productKey
) public view returns (ProductStatus) {
uint256 incidentDate = getActiveIncidentDateInternal(s, coverKey, productKey);
return getProductStatusOfInternal(s, coverKey, productKey, incidentDate);
}
function getProductStatusOfInternal(
IStore s,
bytes32 coverKey,
bytes32 productKey,
uint256 incidentDate
) public view returns (ProductStatus) {
uint256 value = s.getUintByKey(getProductStatusOfKeyInternal(coverKey, productKey, incidentDate));
return ProductStatus(value);
}
function getProductStatusOfKeyInternal(
bytes32 coverKey,
bytes32 productKey,
uint256 incidentDate
) public pure returns (bytes32) {
return keccak256(abi.encodePacked(ProtoUtilV1.NS_COVER_STATUS, coverKey, productKey, incidentDate));
}
function getCoverLiquidityStakeKeyInternal(bytes32 coverKey) external pure returns (bytes32) {
return keccak256(abi.encodePacked(ProtoUtilV1.NS_COVER_LIQUIDITY_STAKE, coverKey));
}
function getLastDepositHeightKeyInternal(bytes32 coverKey) external pure returns (bytes32) {
return keccak256(abi.encodePacked(ProtoUtilV1.NS_VAULT_DEPOSIT_HEIGHTS, coverKey));
}
function getCoverLiquidityStakeIndividualKeyInternal(bytes32 coverKey, address account) external pure returns (bytes32) {
return keccak256(abi.encodePacked(ProtoUtilV1.NS_COVER_LIQUIDITY_STAKE, coverKey, account));
}
function getBlacklistKeyInternal(
bytes32 coverKey,
bytes32 productKey,
uint256 incidentDate
) external pure returns (bytes32) {
return keccak256(abi.encodePacked(ProtoUtilV1.NS_COVER_CLAIM_BLACKLIST, coverKey, productKey, incidentDate));
}
function getTotalLiquidityUnderProtectionInternal(
IStore s,
bytes32 coverKey,
uint256 precision
) external view returns (uint256 total) {
bool supportsProducts = supportsProductsInternal(s, coverKey);
if (supportsProducts == false) {
return getActiveLiquidityUnderProtectionInternal(s, coverKey, ProtoUtilV1.PRODUCT_KEY_INTENTIONALLY_EMPTY, precision);
}
bytes32[] memory products = _getProducts(s, coverKey);
for (uint256 i = 0; i < products.length; i++) {
total += getActiveLiquidityUnderProtectionInternal(s, coverKey, products[i], precision);
}
}
function _getProducts(IStore s, bytes32 coverKey) private view returns (bytes32[] memory products) {
return s.getBytes32ArrayByKeys(ProtoUtilV1.NS_COVER_PRODUCT, coverKey);
}
function getActiveLiquidityUnderProtectionInternal(
IStore s,
bytes32 coverKey,
bytes32 productKey,
uint256 adjustPrecision
) public view returns (uint256 total) {
(uint256 current, uint256 expiryDate) = _getCurrentCommitment(s, coverKey, productKey);
uint256 future = _getFutureCommitments(s, coverKey, productKey, expiryDate);
total = current + future;
total = (total * adjustPrecision) / ProtoUtilV1.CXTOKEN_PRECISION;
}
function _getCurrentCommitment(
IStore s,
bytes32 coverKey,
bytes32 productKey
) private view returns (uint256 amount, uint256 expiryDate) {
uint256 incidentDateIfAny = getActiveIncidentDateInternal(s, coverKey, productKey);
if (incidentDateIfAny == 0) {
return (0, 0);
}
expiryDate = _getMonthEndDate(incidentDateIfAny);
ICxToken cxToken = ICxToken(getCxTokenByExpiryDateInternal(s, coverKey, productKey, expiryDate));
if (address(cxToken) != address(0)) {
amount = cxToken.totalSupply();
}
}
function _getFutureCommitments(
IStore s,
bytes32 coverKey,
bytes32 productKey,
uint256 excludedExpiryDate
) private view returns (uint256 sum) {
for (uint256 i = 0; i <= ProtoUtilV1.MAX_POLICY_DURATION; i++) {
uint256 expiryDate = _getNextMonthEndDate(block.timestamp, i);
if (expiryDate == excludedExpiryDate || expiryDate <= block.timestamp) {
continue;
}
ICxToken cxToken = ICxToken(getCxTokenByExpiryDateInternal(s, coverKey, productKey, expiryDate));
if (address(cxToken) != address(0)) {
sum += cxToken.totalSupply();
}
}
}
function setStatusInternal(
IStore s,
bytes32 coverKey,
bytes32 productKey,
uint256 incidentDate,
ProductStatus status
) external {
s.setUintByKey(getProductStatusOfKeyInternal(coverKey, productKey, incidentDate), uint256(status));
}
function getExpiryDateInternal(uint256 today, uint256 coverDuration) external pure returns (uint256) {
(, , uint256 day) = BokkyPooBahsDateTimeLibrary.timestampToDate(today);
uint256 monthToAdd = coverDuration - 1;
if (day >= 25) {
monthToAdd += 1;
}
return _getNextMonthEndDate(today, monthToAdd);
}
function _getNextMonthEndDate(uint256 date, uint256 monthsToAdd) private pure returns (uint256) {
uint256 futureDate = BokkyPooBahsDateTimeLibrary.addMonths(date, monthsToAdd);
return _getMonthEndDate(futureDate);
}
function _getMonthEndDate(uint256 date) private pure returns (uint256) {
(uint256 year, uint256 month, ) = BokkyPooBahsDateTimeLibrary.timestampToDate(date);
uint256 daysInMonth = BokkyPooBahsDateTimeLibrary._getDaysInMonth(year, month);
return BokkyPooBahsDateTimeLibrary.timestampFromDateTime(year, month, daysInMonth, 23, 59, 59);
}
function getCxTokenByExpiryDateInternal(
IStore s,
bytes32 coverKey,
bytes32 productKey,
uint256 expiryDate
) public view returns (address cxToken) {
bytes32 k = keccak256(abi.encodePacked(ProtoUtilV1.NS_COVER_CXTOKEN, coverKey, productKey, expiryDate));
cxToken = s.getAddress(k);
}
function checkIfProductRequiresWhitelistInternal(
IStore s,
bytes32 coverKey,
bytes32 productKey
) external view returns (bool) {
return s.getBoolByKeys(ProtoUtilV1.NS_COVER_REQUIRES_WHITELIST, coverKey, productKey);
}
function checkIfRequiresWhitelistInternal(IStore s, bytes32 coverKey) external view returns (bool) {
return s.getBoolByKeys(ProtoUtilV1.NS_COVER_REQUIRES_WHITELIST, coverKey);
}
function supportsProductsInternal(IStore s, bytes32 coverKey) public view returns (bool) {
return s.getBoolByKeys(ProtoUtilV1.NS_COVER_SUPPORTS_PRODUCTS, coverKey);
}
function isValidProductInternal(
IStore s,
bytes32 coverKey,
bytes32 productKey
) external view returns (bool) {
return s.getBoolByKeys(ProtoUtilV1.NS_COVER_PRODUCT, coverKey, productKey);
}
function isActiveProductInternal(
IStore s,
bytes32 coverKey,
bytes32 productKey
) external view returns (bool) {
return s.getUintByKeys(ProtoUtilV1.NS_COVER_PRODUCT, coverKey, productKey) == 1;
}
function disablePolicyInternal(
IStore s,
bytes32 coverKey,
bytes32 productKey,
bool status
) external {
bytes32 key = getPolicyDisabledKeyInternal(coverKey, productKey);
s.setBoolByKey(key, status);
}
function isPolicyDisabledInternal(
IStore s,
bytes32 coverKey,
bytes32 productKey
) external view returns (bool) {
bytes32 key = getPolicyDisabledKeyInternal(coverKey, productKey);
return s.getBoolByKey(key);
}
function getPolicyDisabledKeyInternal(bytes32 coverKey, bytes32 productKey) public pure returns (bytes32) {
return keccak256(abi.encodePacked(ProtoUtilV1.NS_POLICY_DISABLED, coverKey, productKey));
}
function getActiveIncidentDateInternal(
IStore s,
bytes32 coverKey,
bytes32 productKey
) public view returns (uint256) {
return s.getUintByKeys(ProtoUtilV1.NS_GOVERNANCE_REPORTING_INCIDENT_DATE, coverKey, productKey);
}
function getCoverageLagInternal(IStore s, bytes32 coverKey) internal view returns (uint256) {
uint256 custom = s.getUintByKeys(ProtoUtilV1.NS_COVERAGE_LAG, coverKey);
if (custom > 0) {
return custom;
}
uint256 global = s.getUintByKey(ProtoUtilV1.NS_COVERAGE_LAG);
if (global > 0) {
return global;
}
return COVER_LAG_FALLBACK_VALUE;
}
}
文件 7 的 54: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 {}
}
文件 8 的 54:GovernanceUtilV1.sol
pragma solidity ^0.8.0;
import "openzeppelin-solidity/contracts/token/ERC20/IERC20.sol";
import "../interfaces/IStore.sol";
import "../interfaces/IPolicy.sol";
import "../interfaces/ICoverStake.sol";
import "../interfaces/IUnstakable.sol";
import "../interfaces/ICoverReassurance.sol";
import "../interfaces/IVault.sol";
import "../interfaces/IVaultFactory.sol";
import "./RoutineInvokerLibV1.sol";
library GovernanceUtilV1 {
using CoverUtilV1 for IStore;
using RoutineInvokerLibV1 for IStore;
using StoreKeyUtil for IStore;
function getReportingPeriodInternal(IStore s, bytes32 coverKey) external view returns (uint256) {
return s.getUintByKeys(ProtoUtilV1.NS_GOVERNANCE_REPORTING_PERIOD, coverKey);
}
function getReportingBurnRateInternal(IStore s) public view returns (uint256) {
return s.getUintByKey(ProtoUtilV1.NS_GOVERNANCE_REPORTING_BURN_RATE);
}
function getGovernanceReporterCommissionInternal(IStore s) public view returns (uint256) {
return s.getUintByKey(ProtoUtilV1.NS_GOVERNANCE_REPORTER_COMMISSION);
}
function getPlatformCoverFeeRateInternal(IStore s) external view returns (uint256) {
return s.getUintByKey(ProtoUtilV1.NS_COVER_PLATFORM_FEE);
}
function getClaimReporterCommissionInternal(IStore s) external view returns (uint256) {
return s.getUintByKey(ProtoUtilV1.NS_CLAIM_REPORTER_COMMISSION);
}
function getMinReportingStakeInternal(IStore s, bytes32 coverKey) external view returns (uint256) {
uint256 fb = s.getUintByKey(ProtoUtilV1.NS_GOVERNANCE_REPORTING_MIN_FIRST_STAKE);
uint256 custom = s.getUintByKeys(ProtoUtilV1.NS_GOVERNANCE_REPORTING_MIN_FIRST_STAKE, coverKey);
return custom > 0 ? custom : fb;
}
function getResolutionTimestampInternal(
IStore s,
bytes32 coverKey,
bytes32 productKey
) external view returns (uint256) {
return s.getUintByKeys(ProtoUtilV1.NS_GOVERNANCE_RESOLUTION_TS, coverKey, productKey);
}
function getReporterInternal(
IStore s,
bytes32 coverKey,
bytes32 productKey,
uint256 incidentDate
) external view returns (address) {
CoverUtilV1.ProductStatus status = s.getProductStatusOfInternal(coverKey, productKey, incidentDate);
bool incidentHappened = status == CoverUtilV1.ProductStatus.IncidentHappened || status == CoverUtilV1.ProductStatus.Claimable;
bytes32 prefix = incidentHappened ? ProtoUtilV1.NS_GOVERNANCE_REPORTING_WITNESS_YES : ProtoUtilV1.NS_GOVERNANCE_REPORTING_WITNESS_NO;
return s.getAddressByKeys(prefix, coverKey, productKey);
}
function getStakesInternal(
IStore s,
bytes32 coverKey,
bytes32 productKey,
uint256 incidentDate
) public view returns (uint256 yes, uint256 no) {
yes = s.getUintByKey(_getIncidentOccurredStakesKey(coverKey, productKey, incidentDate));
no = s.getUintByKey(_getFalseReportingStakesKey(coverKey, productKey, incidentDate));
}
function _getReporterKey(bytes32 coverKey, bytes32 productKey) private pure returns (bytes32) {
return keccak256(abi.encodePacked(ProtoUtilV1.NS_GOVERNANCE_REPORTING_WITNESS_YES, coverKey, productKey));
}
function _getIncidentOccurredStakesKey(
bytes32 coverKey,
bytes32 productKey,
uint256 incidentDate
) private pure returns (bytes32) {
return keccak256(abi.encodePacked(ProtoUtilV1.NS_GOVERNANCE_REPORTING_WITNESS_YES, coverKey, productKey, incidentDate));
}
function _getClaimPayoutsKey(
bytes32 coverKey,
bytes32 productKey,
uint256 incidentDate
) private pure returns (bytes32) {
return keccak256(abi.encodePacked(ProtoUtilV1.NS_CLAIM_PAYOUTS, coverKey, productKey, incidentDate));
}
function _getReassurancePayoutKey(
bytes32 coverKey,
bytes32 productKey,
uint256 incidentDate
) private pure returns (bytes32) {
return keccak256(abi.encodePacked(ProtoUtilV1.NS_COVER_REASSURANCE_PAYOUT, coverKey, productKey, incidentDate));
}
function _getIndividualIncidentOccurredStakeKey(
bytes32 coverKey,
bytes32 productKey,
uint256 incidentDate,
address account
) private pure returns (bytes32) {
return keccak256(abi.encodePacked(ProtoUtilV1.NS_GOVERNANCE_REPORTING_STAKE_OWNED_YES, coverKey, productKey, incidentDate, account));
}
function _getDisputerKey(bytes32 coverKey, bytes32 productKey) private pure returns (bytes32) {
return keccak256(abi.encodePacked(ProtoUtilV1.NS_GOVERNANCE_REPORTING_WITNESS_NO, coverKey, productKey));
}
function _getFalseReportingStakesKey(
bytes32 coverKey,
bytes32 productKey,
uint256 incidentDate
) private pure returns (bytes32) {
return keccak256(abi.encodePacked(ProtoUtilV1.NS_GOVERNANCE_REPORTING_WITNESS_NO, coverKey, productKey, incidentDate));
}
function _getIndividualFalseReportingStakeKey(
bytes32 coverKey,
bytes32 productKey,
uint256 incidentDate,
address account
) private pure returns (bytes32) {
return keccak256(abi.encodePacked(ProtoUtilV1.NS_GOVERNANCE_REPORTING_STAKE_OWNED_NO, coverKey, productKey, incidentDate, account));
}
function getStakesOfInternal(
IStore s,
address account,
bytes32 coverKey,
bytes32 productKey,
uint256 incidentDate
) public view returns (uint256 yes, uint256 no) {
yes = s.getUintByKey(_getIndividualIncidentOccurredStakeKey(coverKey, productKey, incidentDate, account));
no = s.getUintByKey(_getIndividualFalseReportingStakeKey(coverKey, productKey, incidentDate, account));
}
function getResolutionInfoForInternal(
IStore s,
address account,
bytes32 coverKey,
bytes32 productKey,
uint256 incidentDate
)
public
view
returns (
uint256 totalStakeInWinningCamp,
uint256 totalStakeInLosingCamp,
uint256 myStakeInWinningCamp
)
{
(uint256 yes, uint256 no) = getStakesInternal(s, coverKey, productKey, incidentDate);
(uint256 myYes, uint256 myNo) = getStakesOfInternal(s, account, coverKey, productKey, incidentDate);
CoverUtilV1.ProductStatus decision = s.getProductStatusOfInternal(coverKey, productKey, incidentDate);
bool incidentHappened = decision == CoverUtilV1.ProductStatus.IncidentHappened || decision == CoverUtilV1.ProductStatus.Claimable;
totalStakeInWinningCamp = incidentHappened ? yes : no;
totalStakeInLosingCamp = incidentHappened ? no : yes;
myStakeInWinningCamp = incidentHappened ? myYes : myNo;
}
function getUnstakeInfoForInternal(
IStore s,
address account,
bytes32 coverKey,
bytes32 productKey,
uint256 incidentDate
) external view returns (IUnstakable.UnstakeInfoType memory info) {
(info.totalStakeInWinningCamp, info.totalStakeInLosingCamp, info.myStakeInWinningCamp) = getResolutionInfoForInternal(s, account, coverKey, productKey, incidentDate);
info.unstaken = getReportingUnstakenAmountInternal(s, account, coverKey, productKey, incidentDate);
require(info.myStakeInWinningCamp > 0, "Nothing to unstake");
uint256 rewardRatio = (info.myStakeInWinningCamp * ProtoUtilV1.MULTIPLIER) / info.totalStakeInWinningCamp;
uint256 reward = 0;
if (s.getActiveIncidentDateInternal(coverKey, productKey) == incidentDate) {
reward = (info.totalStakeInLosingCamp * rewardRatio) / ProtoUtilV1.MULTIPLIER;
}
require(getReportingBurnRateInternal(s) + getGovernanceReporterCommissionInternal(s) <= ProtoUtilV1.MULTIPLIER, "Invalid configuration");
info.toBurn = (reward * getReportingBurnRateInternal(s)) / ProtoUtilV1.MULTIPLIER;
info.toReporter = (reward * getGovernanceReporterCommissionInternal(s)) / ProtoUtilV1.MULTIPLIER;
info.myReward = reward - info.toBurn - info.toReporter;
}
function getReportingUnstakenAmountInternal(
IStore s,
address account,
bytes32 coverKey,
bytes32 productKey,
uint256 incidentDate
) public view returns (uint256) {
bytes32 k = keccak256(abi.encodePacked(ProtoUtilV1.NS_GOVERNANCE_UNSTAKEN, coverKey, productKey, incidentDate, account));
return s.getUintByKey(k);
}
function updateUnstakeDetailsInternal(
IStore s,
address account,
bytes32 coverKey,
bytes32 productKey,
uint256 incidentDate,
uint256 originalStake,
uint256 reward,
uint256 burned,
uint256 reporterFee
) external {
bytes32 k = keccak256(abi.encodePacked(ProtoUtilV1.NS_GOVERNANCE_UNSTAKE_TS, coverKey, productKey, incidentDate, account));
s.setUintByKey(k, block.timestamp);
k = keccak256(abi.encodePacked(ProtoUtilV1.NS_GOVERNANCE_UNSTAKE_TS, coverKey, productKey, incidentDate));
s.setUintByKey(k, block.timestamp);
k = keccak256(abi.encodePacked(ProtoUtilV1.NS_GOVERNANCE_UNSTAKEN, coverKey, productKey, incidentDate, account));
s.setUintByKey(k, originalStake);
k = keccak256(abi.encodePacked(ProtoUtilV1.NS_GOVERNANCE_UNSTAKEN, coverKey, productKey, incidentDate));
s.addUintByKey(k, originalStake);
if (reward > 0) {
k = keccak256(abi.encodePacked(ProtoUtilV1.NS_GOVERNANCE_UNSTAKE_REWARD, coverKey, productKey, incidentDate, account));
s.setUintByKey(k, reward);
k = keccak256(abi.encodePacked(ProtoUtilV1.NS_GOVERNANCE_UNSTAKE_REWARD, coverKey, productKey, incidentDate));
s.addUintByKey(k, reward);
}
if (burned > 0) {
k = keccak256(abi.encodePacked(ProtoUtilV1.NS_GOVERNANCE_UNSTAKE_BURNED, coverKey, productKey, incidentDate));
s.addUintByKey(k, burned);
}
if (reporterFee > 0) {
k = keccak256(abi.encodePacked(ProtoUtilV1.NS_GOVERNANCE_UNSTAKE_REPORTER_FEE, coverKey, productKey, incidentDate));
s.addUintByKey(k, reporterFee);
}
}
function _updateProductStatusBeforeResolutionInternal(
IStore s,
bytes32 coverKey,
bytes32 productKey,
uint256 incidentDate
) private {
require(incidentDate > 0, "Invalid incident date");
uint256 yes = s.getUintByKey(_getIncidentOccurredStakesKey(coverKey, productKey, incidentDate));
uint256 no = s.getUintByKey(_getFalseReportingStakesKey(coverKey, productKey, incidentDate));
if (no > yes) {
s.setStatusInternal(coverKey, productKey, incidentDate, CoverUtilV1.ProductStatus.FalseReporting);
return;
}
s.setStatusInternal(coverKey, productKey, incidentDate, CoverUtilV1.ProductStatus.IncidentHappened);
}
function addAttestationInternal(
IStore s,
bytes32 coverKey,
bytes32 productKey,
address who,
uint256 incidentDate,
uint256 stake
) external {
mustNotExceedNpmThreshold(stake);
s.addUintByKey(_getIndividualIncidentOccurredStakeKey(coverKey, productKey, incidentDate, who), stake);
uint256 currentStake = s.getUintByKey(_getIncidentOccurredStakesKey(coverKey, productKey, incidentDate));
if (currentStake == 0) {
s.setAddressByKey(_getReporterKey(coverKey, productKey), who);
}
s.addUintByKey(_getIncidentOccurredStakesKey(coverKey, productKey, incidentDate), stake);
_updateProductStatusBeforeResolutionInternal(s, coverKey, productKey, incidentDate);
s.updateStateAndLiquidityInternal(coverKey);
}
function getAttestationInternal(
IStore s,
bytes32 coverKey,
bytes32 productKey,
address who,
uint256 incidentDate
) external view returns (uint256 myStake, uint256 totalStake) {
myStake = s.getUintByKey(_getIndividualIncidentOccurredStakeKey(coverKey, productKey, incidentDate, who));
totalStake = s.getUintByKey(_getIncidentOccurredStakesKey(coverKey, productKey, incidentDate));
}
function addRefutationInternal(
IStore s,
bytes32 coverKey,
bytes32 productKey,
address who,
uint256 incidentDate,
uint256 stake
) external {
mustNotExceedNpmThreshold(stake);
s.addUintByKey(_getIndividualFalseReportingStakeKey(coverKey, productKey, incidentDate, who), stake);
uint256 currentStake = s.getUintByKey(_getFalseReportingStakesKey(coverKey, productKey, incidentDate));
if (currentStake == 0) {
s.setAddressByKey(_getDisputerKey(coverKey, productKey), who);
s.setBoolByKey(getHasDisputeKeyInternal(coverKey, productKey), true);
}
s.addUintByKey(_getFalseReportingStakesKey(coverKey, productKey, incidentDate), stake);
_updateProductStatusBeforeResolutionInternal(s, coverKey, productKey, incidentDate);
s.updateStateAndLiquidityInternal(coverKey);
}
function getHasDisputeKeyInternal(bytes32 coverKey, bytes32 productKey) public pure returns (bytes32) {
return keccak256(abi.encodePacked(ProtoUtilV1.NS_GOVERNANCE_REPORTING_HAS_A_DISPUTE, coverKey, productKey));
}
function getHasFinalizedKeyInternal(
bytes32 coverKey,
bytes32 productKey,
uint256 incidentDate
) public pure returns (bytes32) {
return keccak256(abi.encodePacked(ProtoUtilV1.NS_GOVERNANCE_REPORTING_FINALIZATION, coverKey, productKey, incidentDate));
}
function getRefutationInternal(
IStore s,
bytes32 coverKey,
bytes32 productKey,
address who,
uint256 incidentDate
) external view returns (uint256 myStake, uint256 totalStake) {
myStake = s.getUintByKey(_getIndividualFalseReportingStakeKey(coverKey, productKey, incidentDate, who));
totalStake = s.getUintByKey(_getFalseReportingStakesKey(coverKey, productKey, incidentDate));
}
function getCoolDownPeriodInternal(IStore s, bytes32 coverKey) external view returns (uint256) {
uint256 fromKey = s.getUintByKeys(ProtoUtilV1.NS_RESOLUTION_COOL_DOWN_PERIOD, coverKey);
uint256 fallbackValue = s.getUintByKey(ProtoUtilV1.NS_RESOLUTION_COOL_DOWN_PERIOD);
return fromKey > 0 ? fromKey : fallbackValue;
}
function getResolutionDeadlineInternal(
IStore s,
bytes32 coverKey,
bytes32 productKey
) external view returns (uint256) {
return s.getUintByKeys(ProtoUtilV1.NS_RESOLUTION_DEADLINE, coverKey, productKey);
}
function addClaimPayoutsInternal(
IStore s,
bytes32 coverKey,
bytes32 productKey,
uint256 incidentDate,
uint256 claimed
) external {
s.addUintByKey(_getClaimPayoutsKey(coverKey, productKey, incidentDate), claimed);
}
function getClaimPayoutsInternal(
IStore s,
bytes32 coverKey,
bytes32 productKey,
uint256 incidentDate
) public view returns (uint256) {
return s.getUintByKey(_getClaimPayoutsKey(coverKey, productKey, incidentDate));
}
function getReassurancePayoutInternal(
IStore s,
bytes32 coverKey,
bytes32 productKey,
uint256 incidentDate
) public view returns (uint256) {
return s.getUintByKey(_getReassurancePayoutKey(coverKey, productKey, incidentDate));
}
function addReassurancePayoutInternal(
IStore s,
bytes32 coverKey,
bytes32 productKey,
uint256 incidentDate,
uint256 capitalized
) external {
s.addUintByKey(_getReassurancePayoutKey(coverKey, productKey, incidentDate), capitalized);
}
function getReassuranceTransferrableInternal(
IStore s,
bytes32 coverKey,
bytes32 productKey,
uint256 incidentDate
) external view returns (uint256) {
uint256 reassuranceRate = s.getReassuranceRateInternal(coverKey);
uint256 available = s.getReassuranceAmountInternal(coverKey);
uint256 reassurancePaid = getReassurancePayoutInternal(s, coverKey, productKey, incidentDate);
uint256 totalReassurance = available + reassurancePaid;
uint256 claimsPaid = getClaimPayoutsInternal(s, coverKey, productKey, incidentDate);
uint256 principal = claimsPaid <= totalReassurance ? claimsPaid : totalReassurance;
uint256 transferAmount = (principal * reassuranceRate) / ProtoUtilV1.MULTIPLIER;
return transferAmount - reassurancePaid;
}
function mustNotExceedNpmThreshold(uint256 amount) public pure {
require(amount <= ProtoUtilV1.MAX_NPM_STAKE * 1 ether, "NPM stake is above threshold");
}
}
文件 9 的 54:IAccessControl.sol
pragma solidity ^0.8.0;
interface IAccessControl {
event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);
event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);
event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);
function hasRole(bytes32 role, address account) external view returns (bool);
function getRoleAdmin(bytes32 role) external view returns (bytes32);
function grantRole(bytes32 role, address account) external;
function revokeRole(bytes32 role, address account) external;
function renounceRole(bytes32 role, address account) external;
}
文件 10 的 54:IBondPool.sol
pragma solidity ^0.8.0;
import "./IMember.sol";
interface IBondPool is IMember {
struct BondPoolInfoType {
address lpToken;
uint256 marketPrice;
uint256 discountRate;
uint256 vestingTerm;
uint256 maxBond;
uint256 totalNpmAllocated;
uint256 totalNpmDistributed;
uint256 npmAvailable;
uint256 bondContribution;
uint256 claimable;
uint256 unlockDate;
}
struct SetupBondPoolArgs {
address lpToken;
address treasury;
uint256 bondDiscountRate;
uint256 maxBondAmount;
uint256 vestingTerm;
uint256 npmToTopUpNow;
}
event BondPoolSetup(SetupBondPoolArgs args);
event BondCreated(address indexed account, uint256 lpTokens, uint256 npmToVest, uint256 unlockDate);
event BondClaimed(address indexed account, uint256 amount);
function setup(SetupBondPoolArgs calldata args) external;
function createBond(uint256 lpTokens, uint256 minNpmDesired) external;
function claimBond() external;
function getNpmMarketPrice() external view returns (uint256);
function calculateTokensForLp(uint256 lpTokens) external view returns (uint256);
function getInfo(address forAccount) external view returns (BondPoolInfoType memory info);
}
文件 11 的 54:ICover.sol
pragma solidity ^0.8.0;
import "./IMember.sol";
interface ICover is IMember {
struct AddCoverArgs {
bytes32 coverKey;
string info;
string tokenName;
string tokenSymbol;
bool supportsProducts;
bool requiresWhitelist;
uint256 stakeWithFee;
uint256 initialReassuranceAmount;
uint256 minStakeToReport;
uint256 reportingPeriod;
uint256 cooldownPeriod;
uint256 claimPeriod;
uint256 floor;
uint256 ceiling;
uint256 reassuranceRate;
uint256 leverageFactor;
}
struct AddProductArgs {
bytes32 coverKey;
bytes32 productKey;
string info;
bool requiresWhitelist;
uint256 productStatus;
uint256 efficiency;
}
struct UpdateProductArgs {
bytes32 coverKey;
bytes32 productKey;
string info;
uint256 productStatus;
uint256 efficiency;
}
event CoverCreated(bytes32 indexed coverKey, string info, string tokenName, string tokenSymbol, bool indexed supportsProducts, bool indexed requiresWhitelist);
event ProductCreated(bytes32 indexed coverKey, bytes32 productKey, string info);
event CoverUpdated(bytes32 indexed coverKey, string info);
event ProductUpdated(bytes32 indexed coverKey, bytes32 productKey, string info);
event ProductStateUpdated(bytes32 indexed coverKey, bytes32 indexed productKey, address indexed updatedBy, bool status, string reason);
event CoverCreatorWhitelistUpdated(address account, bool status);
event CoverUserWhitelistUpdated(bytes32 indexed coverKey, bytes32 indexed productKey, address indexed account, bool status);
event CoverCreationFeeSet(uint256 previous, uint256 current);
event MinCoverCreationStakeSet(uint256 previous, uint256 current);
event MinStakeToAddLiquiditySet(uint256 previous, uint256 current);
event CoverInitialized(address indexed stablecoin, bytes32 withName);
function initialize(address stablecoin, bytes32 friendlyName) external;
function addCover(AddCoverArgs calldata args) external returns (address);
function addCovers(AddCoverArgs[] calldata args) external returns (address[] memory vaults);
function addProduct(AddProductArgs calldata args) external;
function addProducts(AddProductArgs[] calldata args) external;
function updateProduct(UpdateProductArgs calldata args) external;
function updateCover(bytes32 coverKey, string calldata info) external;
function updateCoverCreatorWhitelist(address[] calldata account, bool[] calldata whitelisted) external;
function updateCoverUsersWhitelist(
bytes32 coverKey,
bytes32 productKey,
address[] calldata accounts,
bool[] calldata statuses
) external;
function disablePolicy(
bytes32 coverKey,
bytes32 productKey,
bool status,
string calldata reason
) external;
function checkIfWhitelistedCoverCreator(address account) external view returns (bool);
function checkIfWhitelistedUser(
bytes32 coverKey,
bytes32 productKey,
address account
) external view returns (bool);
function setCoverCreationFee(uint256 value) external;
function setMinCoverCreationStake(uint256 value) external;
function setMinStakeToAddLiquidity(uint256 value) external;
}
文件 12 的 54:ICoverReassurance.sol
pragma solidity ^0.8.0;
import "./IMember.sol";
interface ICoverReassurance is IMember {
event ReassuranceAdded(bytes32 indexed coverKey, address indexed onBehalfOf, uint256 amount);
event WeightSet(bytes32 indexed coverKey, uint256 weight);
event PoolCapitalized(bytes32 indexed coverKey, bytes32 indexed productKey, uint256 indexed incidentDate, uint256 amount);
function addReassurance(
bytes32 coverKey,
address onBehalfOf,
uint256 amount
) external;
function setWeight(bytes32 coverKey, uint256 weight) external;
function capitalizePool(
bytes32 coverKey,
bytes32 productKey,
uint256 incidentDate
) external;
function getReassurance(bytes32 coverKey) external view returns (uint256);
}
文件 13 的 54:ICoverStake.sol
pragma solidity ^0.8.0;
import "./IMember.sol";
interface ICoverStake is IMember {
event StakeAdded(bytes32 indexed coverKey, address indexed account, uint256 amount);
event StakeRemoved(bytes32 indexed coverKey, address indexed account, uint256 amount);
event FeeBurned(bytes32 indexed coverKey, uint256 amount);
function increaseStake(
bytes32 coverKey,
address account,
uint256 amount,
uint256 fee
) external;
function decreaseStake(bytes32 coverKey, uint256 amount) external;
function stakeOf(bytes32 coverKey, address account) external view returns (uint256);
}
文件 14 的 54:ICxToken.sol
import "openzeppelin-solidity/contracts/token/ERC20/IERC20.sol";
pragma solidity ^0.8.0;
interface ICxToken is IERC20 {
event CoverageStartSet(uint256 policyId, bytes32 coverKey, bytes32 productKey, address account, uint256 effectiveFrom, uint256 amount);
function mint(
uint256 policyId,
bytes32 coverKey,
bytes32 productKey,
address to,
uint256 amount
) external;
function burn(uint256 amount) external;
function createdOn() external view returns (uint256);
function expiresOn() external view returns (uint256);
function COVER_KEY() external view returns (bytes32);
function PRODUCT_KEY() external view returns (bytes32);
function getCoverageStartsFrom(address account, uint256 date) external view returns (uint256);
function getClaimablePolicyOf(address account) external view returns (uint256);
}
文件 15 的 54:ICxTokenFactory.sol
pragma solidity ^0.8.0;
import "./IStore.sol";
import "./IMember.sol";
interface ICxTokenFactory is IMember {
event CxTokenDeployed(address cxToken, IStore store, bytes32 indexed coverKey, bytes32 indexed productKey, string tokenName, uint256 indexed expiryDate);
function deploy(
bytes32 coverKey,
bytes32 productKey,
string calldata tokenName,
uint256 expiryDate
) external returns (address);
}
文件 16 的 54: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);
}
文件 17 的 54:IERC20Detailed.sol
import "openzeppelin-solidity/contracts/token/ERC20/IERC20.sol";
pragma solidity ^0.8.0;
interface IERC20Detailed is IERC20 {
function name() external view returns (string memory);
function symbol() external view returns (string memory);
function decimals() external view returns (uint8);
function mint(uint256 amount) external;
}
文件 18 的 54: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);
}
文件 19 的 54:IERC3156FlashBorrower.sol
pragma solidity ^0.8.0;
interface IERC3156FlashBorrower {
function onFlashLoan(
address initiator,
address token,
uint256 amount,
uint256 fee,
bytes calldata data
) external returns (bytes32);
}
文件 20 的 54:IERC3156FlashLender.sol
pragma solidity ^0.8.0;
import "./IERC3156FlashBorrower.sol";
interface IERC3156FlashLender {
function maxFlashLoan(address token) external view returns (uint256);
function flashFee(address token, uint256 amount) external view returns (uint256);
function flashLoan(
IERC3156FlashBorrower receiver,
address token,
uint256 amount,
bytes calldata data
) external returns (bool);
}
文件 21 的 54:IGovernance.sol
pragma solidity ^0.8.0;
import "./IReporter.sol";
import "./IWitness.sol";
import "./IMember.sol";
interface IGovernance is IMember, IReporter, IWitness {
}
文件 22 的 54:ILendingStrategy.sol
import "openzeppelin-solidity/contracts/token/ERC20/IERC20.sol";
import "./IMember.sol";
pragma solidity ^0.8.0;
interface ILendingStrategy is IMember {
struct LendingStrategyInfoType {
uint256 deposits;
uint256 withdrawals;
}
event LogDeposit(bytes32 indexed name, uint256 counter, uint256 amount, uint256 certificateReceived, uint256 depositTotal, uint256 withdrawalTotal);
event Deposited(bytes32 indexed key, address indexed onBehalfOf, uint256 stablecoinDeposited, uint256 certificateTokenIssued);
event LogWithdrawal(bytes32 indexed name, uint256 counter, uint256 stablecoinWithdrawn, uint256 certificateRedeemed, uint256 depositTotal, uint256 withdrawalTotal);
event Withdrawn(bytes32 indexed key, address indexed sendTo, uint256 stablecoinWithdrawn, uint256 certificateTokenRedeemed);
event Drained(IERC20 indexed asset, uint256 amount);
function getKey() external pure returns (bytes32);
function getWeight() external pure returns (uint256);
function getDepositAsset() external view returns (IERC20);
function getDepositCertificate() external view returns (IERC20);
function getInfo(bytes32 coverKey) external view returns (LendingStrategyInfoType memory info);
function deposit(bytes32 coverKey, uint256 amount) external returns (uint256 certificateReceived);
function withdraw(bytes32 coverKey) external returns (uint256 stablecoinWithdrawn);
}
文件 23 的 54:IMember.sol
pragma solidity ^0.8.0;
interface IMember {
function version() external pure returns (bytes32);
function getName() external pure returns (bytes32);
}
文件 24 的 54:IPausable.sol
pragma solidity ^0.8.0;
interface IPausable {
function paused() external view returns (bool);
}
文件 25 的 54:IPolicy.sol
pragma solidity ^0.8.0;
import "./IMember.sol";
interface IPolicy is IMember {
struct PurchaseCoverArgs {
address onBehalfOf;
bytes32 coverKey;
bytes32 productKey;
uint256 coverDuration;
uint256 amountToCover;
bytes32 referralCode;
}
struct CoverFeeInfoType {
uint256 fee;
uint256 utilizationRatio;
uint256 totalAvailableLiquidity;
uint256 floor;
uint256 ceiling;
uint256 rate;
}
struct CoverPoolSummaryType {
uint256 totalAmountInPool;
uint256 totalCommitment;
uint256 reassuranceAmount;
uint256 reassurancePoolWeight;
uint256 productCount;
uint256 leverage;
uint256 productCapitalEfficiency;
}
event CoverPurchased(PurchaseCoverArgs args, address indexed cxToken, uint256 fee, uint256 platformFee, uint256 expiresOn, uint256 policyId);
function purchaseCover(PurchaseCoverArgs calldata args) external returns (address, uint256);
function getCoverFeeInfo(
bytes32 coverKey,
bytes32 productKey,
uint256 coverDuration,
uint256 amountToCover
) external view returns (CoverFeeInfoType memory);
function getCoverPoolSummary(bytes32 coverKey, bytes32 productKey) external view returns (CoverPoolSummaryType memory summary);
function getCxToken(
bytes32 coverKey,
bytes32 productKey,
uint256 coverDuration
) external view returns (address cxToken, uint256 expiryDate);
function getCxTokenByExpiryDate(
bytes32 coverKey,
bytes32 productKey,
uint256 expiryDate
) external view returns (address cxToken);
function getCommitment(bytes32 coverKey, bytes32 productKey) external view returns (uint256);
function getAvailableLiquidity(bytes32 coverKey) external view returns (uint256);
function getExpiryDate(uint256 today, uint256 coverDuration) external pure returns (uint256);
}
文件 26 的 54:IPriceOracle.sol
pragma solidity ^0.8.0;
interface IPriceOracle {
function update() external;
function consult(address token, uint256 amountIn) external view returns (uint256 amountOut);
function consultPair(uint256 amountIn) external view returns (uint256);
}
文件 27 的 54:IProtocol.sol
pragma solidity ^0.8.0;
import "openzeppelin-solidity/contracts/token/ERC20/IERC20.sol";
import "openzeppelin-solidity/contracts/access/IAccessControl.sol";
import "./IMember.sol";
interface IProtocol is IMember, IAccessControl {
struct AccountWithRoles {
address account;
bytes32[] roles;
}
struct InitializeArgs {
address burner;
address uniswapV2RouterLike;
address uniswapV2FactoryLike;
address npm;
address treasury;
address priceOracle;
uint256 coverCreationFee;
uint256 minCoverCreationStake;
uint256 minStakeToAddLiquidity;
uint256 firstReportingStake;
uint256 claimPeriod;
uint256 reportingBurnRate;
uint256 governanceReporterCommission;
uint256 claimPlatformFee;
uint256 claimReporterCommission;
uint256 flashLoanFee;
uint256 flashLoanFeeProtocol;
uint256 resolutionCoolDownPeriod;
uint256 stateUpdateInterval;
uint256 maxLendingRatio;
uint256 lendingPeriod;
uint256 withdrawalWindow;
uint256 policyFloor;
uint256 policyCeiling;
}
event Initialized(InitializeArgs args);
event ContractAdded(bytes32 indexed namespace, bytes32 indexed key, address indexed contractAddress);
event ContractUpgraded(bytes32 indexed namespace, bytes32 indexed key, address previous, address indexed current);
event MemberAdded(address member);
event MemberRemoved(address member);
function addContract(bytes32 namespace, address contractAddress) external;
function addContracts(
bytes32[] calldata namespaces,
bytes32[] calldata keys,
address[] calldata contractAddresses
) external;
function addContractWithKey(
bytes32 namespace,
bytes32 coverKey,
address contractAddress
) external;
function initialize(InitializeArgs calldata args) external;
function upgradeContract(
bytes32 namespace,
address previous,
address current
) external;
function upgradeContractWithKey(
bytes32 namespace,
bytes32 coverKey,
address previous,
address current
) external;
function addMember(address member) external;
function removeMember(address member) external;
function grantRoles(AccountWithRoles[] calldata detail) external;
}
文件 28 的 54:IRecoverable.sol
pragma solidity ^0.8.0;
import "./IStore.sol";
interface IRecoverable {
function s() external view returns (IStore);
function recoverEther(address sendTo) external;
function recoverToken(address token, address sendTo) external;
}
文件 29 的 54:IReporter.sol
pragma solidity ^0.8.0;
interface IReporter {
event Reported(bytes32 indexed coverKey, bytes32 indexed productKey, address reporter, uint256 indexed incidentDate, string info, uint256 initialStake, uint256 resolutionTimestamp);
event Disputed(bytes32 indexed coverKey, bytes32 indexed productKey, address reporter, uint256 indexed incidentDate, string info, uint256 initialStake);
event ReportingBurnRateSet(uint256 previous, uint256 current);
event FirstReportingStakeSet(bytes32 coverKey, uint256 previous, uint256 current);
event ReporterCommissionSet(uint256 previous, uint256 current);
function report(
bytes32 coverKey,
bytes32 productKey,
string calldata info,
uint256 stake
) external;
function dispute(
bytes32 coverKey,
bytes32 productKey,
uint256 incidentDate,
string calldata info,
uint256 stake
) external;
function getActiveIncidentDate(bytes32 coverKey, bytes32 productKey) external view returns (uint256);
function getAttestation(
bytes32 coverKey,
bytes32 productKey,
address who,
uint256 incidentDate
) external view returns (uint256 myStake, uint256 totalStake);
function getRefutation(
bytes32 coverKey,
bytes32 productKey,
address who,
uint256 incidentDate
) external view returns (uint256 myStake, uint256 totalStake);
function getReporter(
bytes32 coverKey,
bytes32 productKey,
uint256 incidentDate
) external view returns (address);
function getResolutionTimestamp(bytes32 coverKey, bytes32 productKey) external view returns (uint256);
function setFirstReportingStake(bytes32 coverKey, uint256 value) external;
function getFirstReportingStake(bytes32 coverKey) external view returns (uint256);
function setReportingBurnRate(uint256 value) external;
function setReporterCommission(uint256 value) external;
}
文件 30 的 54:IStore.sol
pragma solidity ^0.8.0;
interface IStore {
event PausersSet(address indexed addedBy, address[] accounts, bool[] statuses);
function setPausers(address[] calldata accounts, bool[] calldata statuses) external;
function setAddress(bytes32 k, address v) external;
function setAddressBoolean(
bytes32 k,
address a,
bool v
) external;
function setUint(bytes32 k, uint256 v) external;
function addUint(bytes32 k, uint256 v) external;
function subtractUint(bytes32 k, uint256 v) external;
function setUints(bytes32 k, uint256[] calldata v) external;
function setString(bytes32 k, string calldata v) external;
function setBytes(bytes32 k, bytes calldata v) external;
function setBool(bytes32 k, bool v) external;
function setInt(bytes32 k, int256 v) external;
function setBytes32(bytes32 k, bytes32 v) external;
function setAddressArrayItem(bytes32 k, address v) external;
function setBytes32ArrayItem(bytes32 k, bytes32 v) external;
function deleteAddress(bytes32 k) external;
function deleteUint(bytes32 k) external;
function deleteUints(bytes32 k) external;
function deleteString(bytes32 k) external;
function deleteBytes(bytes32 k) external;
function deleteBool(bytes32 k) external;
function deleteInt(bytes32 k) external;
function deleteBytes32(bytes32 k) external;
function deleteAddressArrayItem(bytes32 k, address v) external;
function deleteBytes32ArrayItem(bytes32 k, bytes32 v) external;
function deleteAddressArrayItemByIndex(bytes32 k, uint256 i) external;
function deleteBytes32ArrayItemByIndex(bytes32 k, uint256 i) external;
function getAddressValues(bytes32[] calldata keys) external view returns (address[] memory values);
function getAddress(bytes32 k) external view returns (address);
function getAddressBoolean(bytes32 k, address a) external view returns (bool);
function getUintValues(bytes32[] calldata keys) external view returns (uint256[] memory values);
function getUint(bytes32 k) external view returns (uint256);
function getUints(bytes32 k) external view returns (uint256[] memory);
function getString(bytes32 k) external view returns (string memory);
function getBytes(bytes32 k) external view returns (bytes memory);
function getBool(bytes32 k) external view returns (bool);
function getInt(bytes32 k) external view returns (int256);
function getBytes32(bytes32 k) external view returns (bytes32);
function countAddressArrayItems(bytes32 k) external view returns (uint256);
function countBytes32ArrayItems(bytes32 k) external view returns (uint256);
function getAddressArray(bytes32 k) external view returns (address[] memory);
function getBytes32Array(bytes32 k) external view returns (bytes32[] memory);
function getAddressArrayItemPosition(bytes32 k, address toFind) external view returns (uint256);
function getBytes32ArrayItemPosition(bytes32 k, bytes32 toFind) external view returns (uint256);
function getAddressArrayItemByIndex(bytes32 k, uint256 i) external view returns (address);
function getBytes32ArrayItemByIndex(bytes32 k, uint256 i) external view returns (bytes32);
}
文件 31 的 54:IUniswapV2FactoryLike.sol
pragma solidity ^0.8.0;
interface IUniswapV2FactoryLike {
event PairCreated(address indexed token0, address indexed token1, address pair, uint256);
function getPair(address tokenA, address tokenB) external view returns (address pair);
}
文件 32 的 54:IUniswapV2PairLike.sol
pragma solidity ^0.8.0;
interface IUniswapV2PairLike {
function token0() external view returns (address);
function token1() external view returns (address);
function totalSupply() external view returns (uint256);
function getReserves()
external
view
returns (
uint112 reserve0,
uint112 reserve1,
uint32 blockTimestampLast
);
}
文件 33 的 54:IUniswapV2RouterLike.sol
pragma solidity ^0.8.0;
interface IUniswapV2RouterLike {
function factory() external view returns (address);
function getAmountOut(
uint256 amountIn,
uint256 reserveIn,
uint256 reserveOut
) external pure returns (uint256 amountOut);
function getAmountIn(
uint256 amountOut,
uint256 reserveIn,
uint256 reserveOut
) external pure returns (uint256 amountIn);
function getAmountsOut(uint256 amountIn, address[] calldata path) external view returns (uint256[] memory amounts);
function getAmountsIn(uint256 amountOut, address[] calldata path) external view returns (uint256[] memory amounts);
function quote(
uint256 amountA,
uint256 reserveA,
uint256 reserveB
) external pure returns (uint256 amountB);
function addLiquidity(
address tokenA,
address tokenB,
uint256 amountADesired,
uint256 amountBDesired,
uint256 amountAMin,
uint256 amountBMin,
address to,
uint256 deadline
)
external
returns (
uint256 amountA,
uint256 amountB,
uint256 liquidity
);
}
文件 34 的 54:IUnstakable.sol
pragma solidity ^0.8.0;
import "./IStore.sol";
interface IUnstakable {
struct UnstakeInfoType {
uint256 totalStakeInWinningCamp;
uint256 totalStakeInLosingCamp;
uint256 myStakeInWinningCamp;
uint256 toBurn;
uint256 toReporter;
uint256 myReward;
uint256 unstaken;
}
event Unstaken(bytes32 indexed coverKey, bytes32 indexed productKey, address indexed caller, uint256 originalStake, uint256 reward);
event ReporterRewardDistributed(bytes32 indexed coverKey, bytes32 indexed productKey, address caller, address indexed reporter, uint256 originalReward, uint256 reporterReward);
event GovernanceBurned(bytes32 indexed coverKey, bytes32 indexed productKey, address caller, address indexed burner, uint256 originalReward, uint256 burnedAmount);
function unstake(
bytes32 coverKey,
bytes32 productKey,
uint256 incidentDate
) external;
function unstakeWithClaim(
bytes32 coverKey,
bytes32 productKey,
uint256 incidentDate
) external;
function getUnstakeInfoFor(
address account,
bytes32 coverKey,
bytes32 productKey,
uint256 incidentDate
) external view returns (UnstakeInfoType memory);
}
文件 35 的 54:IVault.sol
pragma solidity ^0.8.0;
import "./IMember.sol";
import "openzeppelin-solidity/contracts/token/ERC20/IERC20.sol";
interface IVault is IMember, IERC20 {
struct VaultInfoType {
uint256 totalPods;
uint256 balance;
uint256 extendedBalance;
uint256 totalReassurance;
uint256 myPodBalance;
uint256 myShare;
uint256 withdrawalOpen;
uint256 withdrawalClose;
}
struct AddLiquidityArgs {
bytes32 coverKey;
uint256 amount;
uint256 npmStakeToAdd;
bytes32 referralCode;
}
event GovernanceTransfer(address indexed to, uint256 amount);
event StrategyTransfer(address indexed token, address indexed strategy, bytes32 indexed name, uint256 amount);
event StrategyReceipt(address indexed token, address indexed strategy, bytes32 indexed name, uint256 amount, uint256 income, uint256 loss);
event PodsIssued(address indexed account, uint256 issued, uint256 liquidityAdded, bytes32 indexed referralCode);
event PodsRedeemed(address indexed account, uint256 redeemed, uint256 liquidityReleased);
event FlashLoanBorrowed(address indexed lender, address indexed borrower, address indexed stablecoin, uint256 amount, uint256 fee);
event NpmStaken(address indexed account, uint256 amount);
event NpmUnstaken(address indexed account, uint256 amount);
event InterestAccrued(bytes32 indexed coverKey);
event Entered(bytes32 indexed coverKey, address indexed account);
event Exited(bytes32 indexed coverKey, address indexed account);
function key() external view returns (bytes32);
function sc() external view returns (address);
function addLiquidity(AddLiquidityArgs calldata args) external;
function accrueInterest() external;
function removeLiquidity(
bytes32 coverKey,
uint256 amount,
uint256 npmStake,
bool exit
) external;
function transferGovernance(
bytes32 coverKey,
address to,
uint256 amount
) external;
function transferToStrategy(
IERC20 token,
bytes32 coverKey,
bytes32 strategyName,
uint256 amount
) external;
function receiveFromStrategy(
IERC20 token,
bytes32 coverKey,
bytes32 strategyName,
uint256 amount
) external;
function calculatePods(uint256 forStablecoinUnits) external view returns (uint256);
function calculateLiquidity(uint256 podsToBurn) external view returns (uint256);
function getInfo(address forAccount) external view returns (VaultInfoType memory info);
function getStablecoinBalanceOf() external view returns (uint256);
}
文件 36 的 54:IVaultDelegate.sol
pragma solidity ^0.8.0;
import "./IMember.sol";
import "./IVault.sol";
import "openzeppelin-solidity/contracts/token/ERC20/IERC20.sol";
import "openzeppelin-solidity/contracts/interfaces/IERC3156FlashLender.sol";
interface IVaultDelegate is IMember {
function preAddLiquidity(
address caller,
bytes32 coverKey,
uint256 amount,
uint256 npmStake
) external returns (uint256 podsToMint, uint256 previousNpmStake);
function postAddLiquidity(
address caller,
bytes32 coverKey,
uint256 amount,
uint256 npmStake
) external;
function accrueInterestImplementation(address caller, bytes32 coverKey) external;
function preRemoveLiquidity(
address caller,
bytes32 coverKey,
uint256 amount,
uint256 npmStake,
bool exit
) external returns (address stablecoin, uint256 stableCoinToRelease);
function postRemoveLiquidity(
address caller,
bytes32 coverKey,
uint256 amount,
uint256 npmStake,
bool exit
) external;
function preTransferGovernance(
address caller,
bytes32 coverKey,
address to,
uint256 amount
) external returns (address stablecoin);
function postTransferGovernance(
address caller,
bytes32 coverKey,
address to,
uint256 amount
) external;
function preTransferToStrategy(
address caller,
IERC20 token,
bytes32 coverKey,
bytes32 strategyName,
uint256 amount
) external;
function postTransferToStrategy(
address caller,
IERC20 token,
bytes32 coverKey,
bytes32 strategyName,
uint256 amount
) external;
function preReceiveFromStrategy(
address caller,
IERC20 token,
bytes32 coverKey,
bytes32 strategyName,
uint256 amount
) external;
function postReceiveFromStrategy(
address caller,
IERC20 token,
bytes32 coverKey,
bytes32 strategyName,
uint256 amount
) external returns (uint256 income, uint256 loss);
function preFlashLoan(
address caller,
bytes32 coverKey,
IERC3156FlashBorrower receiver,
address token,
uint256 amount,
bytes calldata data
)
external
returns (
IERC20 stablecoin,
uint256 fee,
uint256 protocolFee
);
function postFlashLoan(
address caller,
bytes32 coverKey,
IERC3156FlashBorrower receiver,
address token,
uint256 amount,
bytes calldata data
) external;
function calculatePodsImplementation(bytes32 coverKey, uint256 forStablecoinUnits) external view returns (uint256);
function calculateLiquidityImplementation(bytes32 coverKey, uint256 podsToBurn) external view returns (uint256);
function getInfoImplementation(bytes32 coverKey, address forAccount) external view returns (IVault.VaultInfoType memory);
function getStablecoinBalanceOfImplementation(bytes32 coverKey) external view returns (uint256);
function getFlashFee(
address caller,
bytes32 coverKey,
address token,
uint256 amount
) external view returns (uint256);
function getMaxFlashLoan(
address caller,
bytes32 coverKey,
address token
) external view returns (uint256);
}
文件 37 的 54:IVaultFactory.sol
pragma solidity ^0.8.0;
import "./IStore.sol";
import "./IMember.sol";
interface IVaultFactory is IMember {
event VaultDeployed(address vault, bytes32 indexed coverKey, string name, string symbol);
function deploy(
bytes32 coverKey,
string calldata name,
string calldata symbol
) external returns (address);
}
文件 38 的 54:IWitness.sol
pragma solidity ^0.8.0;
interface IWitness {
event Attested(bytes32 indexed coverKey, bytes32 indexed productKey, address witness, uint256 indexed incidentDate, uint256 stake);
event Refuted(bytes32 indexed coverKey, bytes32 indexed productKey, address witness, uint256 indexed incidentDate, uint256 stake);
function attest(
bytes32 coverKey,
bytes32 productKey,
uint256 incidentDate,
uint256 stake
) external;
function refute(
bytes32 coverKey,
bytes32 productKey,
uint256 incidentDate,
uint256 stake
) external;
function getStatus(bytes32 coverKey, bytes32 productKey) external view returns (uint256);
function isCoverNormal(bytes32 coverKey) external view returns (bool);
function getStakes(
bytes32 coverKey,
bytes32 productKey,
uint256 incidentDate
) external view returns (uint256, uint256);
function getStakesOf(
bytes32 coverKey,
bytes32 productKey,
uint256 incidentDate,
address account
) external view returns (uint256, uint256);
}
文件 39 的 54:NTransferUtilV2.sol
pragma solidity ^0.8.0;
import "openzeppelin-solidity/contracts/token/ERC20/IERC20.sol";
import "openzeppelin-solidity/contracts/token/ERC20/utils/SafeERC20.sol";
library NTransferUtilV2 {
using SafeERC20 for IERC20;
function ensureApproval(
IERC20 malicious,
address spender,
uint256 amount
) external {
require(address(malicious) != address(0), "Invalid token address");
require(spender != address(0), "Invalid spender");
require(amount > 0, "Invalid transfer amount");
malicious.safeIncreaseAllowance(spender, amount);
}
function ensureTransfer(
IERC20 malicious,
address recipient,
uint256 amount
) external {
require(address(malicious) != address(0), "Invalid token address");
require(recipient != address(0), "Spender can't be zero");
require(amount > 0, "Invalid transfer amount");
uint256 balanceBeforeTransfer = malicious.balanceOf(recipient);
malicious.safeTransfer(recipient, amount);
uint256 balanceAfterTransfer = malicious.balanceOf(recipient);
uint256 actualTransferAmount = balanceAfterTransfer - balanceBeforeTransfer;
require(actualTransferAmount == amount, "Invalid transfer");
}
function ensureTransferFrom(
IERC20 malicious,
address sender,
address recipient,
uint256 amount
) external {
require(address(malicious) != address(0), "Invalid token address");
require(sender != address(0), "Invalid sender");
require(recipient != address(0), "Invalid recipient");
require(amount > 0, "Invalid transfer amount");
uint256 balanceBeforeTransfer = malicious.balanceOf(recipient);
malicious.safeTransferFrom(sender, recipient, amount);
uint256 balanceAfterTransfer = malicious.balanceOf(recipient);
uint256 actualTransferAmount = balanceAfterTransfer - balanceBeforeTransfer;
require(actualTransferAmount == amount, "Invalid transfer");
}
}
文件 40 的 54:PriceLibV1.sol
pragma solidity ^0.8.0;
import "openzeppelin-solidity/contracts/token/ERC20/IERC20.sol";
import "../interfaces/IStore.sol";
import "../interfaces/IPriceOracle.sol";
import "../dependencies/uniswap-v2/IUniswapV2RouterLike.sol";
import "../dependencies/uniswap-v2/IUniswapV2PairLike.sol";
import "../dependencies/uniswap-v2/IUniswapV2FactoryLike.sol";
import "./ProtoUtilV1.sol";
library PriceLibV1 {
using ProtoUtilV1 for IStore;
using StoreKeyUtil for IStore;
function getPriceOracleInternal(IStore s) public view returns (IPriceOracle) {
return IPriceOracle(s.getNpmPriceOracleInternal());
}
function setNpmPrice(IStore s) internal {
IPriceOracle oracle = getPriceOracleInternal(s);
if (address(oracle) == address(0)) {
return;
}
oracle.update();
}
function convertNpmLpUnitsToStabelcoinInternal(IStore s, uint256 amountIn) external view returns (uint256) {
return getPriceOracleInternal(s).consultPair(amountIn);
}
function getLastUpdatedOnInternal(IStore s, bytes32 coverKey) external view returns (uint256) {
bytes32 key = getLastUpdateKeyInternal(coverKey);
return s.getUintByKey(key);
}
function setLastUpdatedOnInternal(IStore s, bytes32 coverKey) external {
bytes32 key = getLastUpdateKeyInternal(coverKey);
s.setUintByKey(key, block.timestamp);
}
function getLastUpdateKeyInternal(bytes32 coverKey) public pure returns (bytes32) {
return keccak256(abi.encodePacked(ProtoUtilV1.NS_LAST_LIQUIDITY_STATE_UPDATE, coverKey));
}
function getNpmPriceInternal(IStore s, uint256 amountIn) external view returns (uint256) {
return getPriceOracleInternal(s).consult(s.getNpmTokenAddressInternal(), amountIn);
}
}
文件 41 的 54:ProtoUtilV1.sol
pragma solidity ^0.8.0;
import "openzeppelin-solidity/contracts/token/ERC20/IERC20.sol";
import "./StoreKeyUtil.sol";
import "../interfaces/IStore.sol";
import "../interfaces/IProtocol.sol";
import "../interfaces/IERC20Detailed.sol";
library ProtoUtilV1 {
using StoreKeyUtil for IStore;
uint256 public constant MAX_POLICY_DURATION = 3;
bytes32 public constant KEY_INTENTIONALLY_EMPTY = 0;
bytes32 public constant PRODUCT_KEY_INTENTIONALLY_EMPTY = 0;
uint256 public constant MULTIPLIER = 10_000;
uint256 public constant MIN_LIQUIDITY = 10;
uint256 public constant MAX_LIQUIDITY = 10_000_000;
uint256 public constant MIN_PROPOSAL_AMOUNT = 10;
uint256 public constant MAX_PROPOSAL_AMOUNT = 10_000_000;
uint256 public constant MAX_NPM_STAKE = 10_000_000;
uint256 public constant NPM_PRECISION = 1 ether;
uint256 public constant CXTOKEN_PRECISION = 1 ether;
uint256 public constant POD_PRECISION = 1 ether;
bytes32 public constant CNS_CORE = "cns:core";
bytes32 public constant CNS_NPM = "cns:core:npm:instance";
bytes32 public constant CNS_COVER = "cns:cover";
bytes32 public constant CNS_UNISWAP_V2_ROUTER = "cns:core:uni:v2:router";
bytes32 public constant CNS_UNISWAP_V2_FACTORY = "cns:core:uni:v2:factory";
bytes32 public constant CNS_PRICE_DISCOVERY = "cns:core:price:discovery";
bytes32 public constant CNS_TREASURY = "cns:core:treasury";
bytes32 public constant CNS_NPM_PRICE_ORACLE = "cns:core:npm:price:oracle";
bytes32 public constant CNS_COVER_REASSURANCE = "cns:cover:reassurance";
bytes32 public constant CNS_POOL_BOND = "cns:pool:bond";
bytes32 public constant CNS_COVER_POLICY = "cns:cover:policy";
bytes32 public constant CNS_COVER_POLICY_MANAGER = "cns:cover:policy:manager";
bytes32 public constant CNS_COVER_POLICY_ADMIN = "cns:cover:policy:admin";
bytes32 public constant CNS_COVER_STAKE = "cns:cover:stake";
bytes32 public constant CNS_COVER_VAULT = "cns:cover:vault";
bytes32 public constant CNS_COVER_VAULT_DELEGATE = "cns:cover:vault:delegate";
bytes32 public constant CNS_COVER_STABLECOIN = "cns:cover:sc";
bytes32 public constant CNS_COVER_CXTOKEN_FACTORY = "cns:cover:cxtoken:factory";
bytes32 public constant CNS_COVER_VAULT_FACTORY = "cns:cover:vault:factory";
bytes32 public constant CNS_BOND_POOL = "cns:pools:bond";
bytes32 public constant CNS_STAKING_POOL = "cns:pools:staking";
bytes32 public constant CNS_LIQUIDITY_ENGINE = "cns:liquidity:engine";
bytes32 public constant CNS_STRATEGY_AAVE = "cns:strategy:aave";
bytes32 public constant CNS_STRATEGY_COMPOUND = "cns:strategy:compound";
bytes32 public constant CNS_GOVERNANCE = "cns:gov";
bytes32 public constant CNS_GOVERNANCE_RESOLUTION = "cns:gov:resolution";
bytes32 public constant CNS_CLAIM_PROCESSOR = "cns:claim:processor";
bytes32 public constant CNS_BURNER = "cns:core:burner";
bytes32 public constant NS_MEMBERS = "ns:members";
bytes32 public constant NS_CONTRACTS = "ns:contracts";
bytes32 public constant NS_COVER = "ns:cover";
bytes32 public constant NS_COVER_PRODUCT = "ns:cover:product";
bytes32 public constant NS_COVER_PRODUCT_EFFICIENCY = "ns:cover:product:efficiency";
bytes32 public constant NS_COVER_CREATION_DATE = "ns:cover:creation:date";
bytes32 public constant NS_COVER_CREATION_FEE = "ns:cover:creation:fee";
bytes32 public constant NS_COVER_CREATION_MIN_STAKE = "ns:cover:creation:min:stake";
bytes32 public constant NS_COVER_REASSURANCE = "ns:cover:reassurance";
bytes32 public constant NS_COVER_REASSURANCE_PAYOUT = "ns:cover:reassurance:payout";
bytes32 public constant NS_COVER_REASSURANCE_WEIGHT = "ns:cover:reassurance:weight";
bytes32 public constant NS_COVER_REASSURANCE_RATE = "ns:cover:reassurance:rate";
bytes32 public constant NS_COVER_LEVERAGE_FACTOR = "ns:cover:leverage:factor";
bytes32 public constant NS_COVER_CREATION_FEE_EARNING = "ns:cover:creation:fee:earning";
bytes32 public constant NS_COVER_INFO = "ns:cover:info";
bytes32 public constant NS_COVER_OWNER = "ns:cover:owner";
bytes32 public constant NS_COVER_SUPPORTS_PRODUCTS = "ns:cover:supports:products";
bytes32 public constant NS_VAULT_STRATEGY_OUT = "ns:vault:strategy:out";
bytes32 public constant NS_VAULT_LENDING_INCOMES = "ns:vault:lending:incomes";
bytes32 public constant NS_VAULT_LENDING_LOSSES = "ns:vault:lending:losses";
bytes32 public constant NS_VAULT_DEPOSIT_HEIGHTS = "ns:vault:deposit:heights";
bytes32 public constant NS_COVER_LIQUIDITY_LENDING_PERIOD = "ns:cover:liquidity:len:p";
bytes32 public constant NS_COVER_LIQUIDITY_MAX_LENDING_RATIO = "ns:cover:liquidity:max:lr";
bytes32 public constant NS_COVER_LIQUIDITY_WITHDRAWAL_WINDOW = "ns:cover:liquidity:ww";
bytes32 public constant NS_COVER_LIQUIDITY_MIN_STAKE = "ns:cover:liquidity:min:stake";
bytes32 public constant NS_COVER_LIQUIDITY_STAKE = "ns:cover:liquidity:stake";
bytes32 public constant NS_COVER_LIQUIDITY_COMMITTED = "ns:cover:liquidity:committed";
bytes32 public constant NS_COVER_STABLECOIN_NAME = "ns:cover:stablecoin:name";
bytes32 public constant NS_COVER_REQUIRES_WHITELIST = "ns:cover:requires:whitelist";
bytes32 public constant NS_COVER_HAS_FLASH_LOAN = "ns:cover:has:fl";
bytes32 public constant NS_COVER_LIQUIDITY_FLASH_LOAN_FEE = "ns:cover:liquidity:fl:fee";
bytes32 public constant NS_COVER_LIQUIDITY_FLASH_LOAN_FEE_PROTOCOL = "ns:proto:cover:liquidity:fl:fee";
bytes32 public constant NS_COVERAGE_LAG = "ns:coverage:lag";
bytes32 public constant NS_COVER_POLICY_RATE_FLOOR = "ns:cover:policy:rate:floor";
bytes32 public constant NS_COVER_POLICY_RATE_CEILING = "ns:cover:policy:rate:ceiling";
bytes32 public constant NS_POLICY_DISABLED = "ns:policy:disabled";
bytes32 public constant NS_POLICY_LAST_PURCHASE_ID = "ns:policy:last:purchase:id";
bytes32 public constant NS_COVER_STAKE = "ns:cover:stake";
bytes32 public constant NS_COVER_STAKE_OWNED = "ns:cover:stake:owned";
bytes32 public constant NS_COVER_STATUS = "ns:cover:status";
bytes32 public constant NS_COVER_CXTOKEN = "ns:cover:cxtoken";
bytes32 public constant NS_VAULT_TOKEN_NAME = "ns:vault:token:name";
bytes32 public constant NS_VAULT_TOKEN_SYMBOL = "ns:vault:token:symbol";
bytes32 public constant NS_COVER_CREATOR_WHITELIST = "ns:cover:creator:whitelist";
bytes32 public constant NS_COVER_USER_WHITELIST = "ns:cover:user:whitelist";
bytes32 public constant NS_COVER_CLAIM_BLACKLIST = "ns:cover:claim:blacklist";
bytes32 public constant NS_GOVERNANCE_RESOLUTION_TS = "ns:gov:resolution:ts";
bytes32 public constant NS_GOVERNANCE_UNSTAKEN = "ns:gov:unstaken";
bytes32 public constant NS_GOVERNANCE_UNSTAKE_TS = "ns:gov:unstake:ts";
bytes32 public constant NS_GOVERNANCE_UNSTAKE_REWARD = "ns:gov:unstake:reward";
bytes32 public constant NS_GOVERNANCE_UNSTAKE_BURNED = "ns:gov:unstake:burned";
bytes32 public constant NS_GOVERNANCE_UNSTAKE_REPORTER_FEE = "ns:gov:unstake:rep:fee";
bytes32 public constant NS_GOVERNANCE_REPORTING_MIN_FIRST_STAKE = "ns:gov:rep:min:first:stake";
bytes32 public constant NS_GOVERNANCE_REPORTING_INCIDENT_DATE = "ns:gov:rep:incident:date";
bytes32 public constant NS_GOVERNANCE_REPORTING_PERIOD = "ns:gov:rep:period";
bytes32 public constant NS_GOVERNANCE_REPORTING_WITNESS_YES = "ns:gov:rep:witness:yes";
bytes32 public constant NS_GOVERNANCE_REPORTING_HAS_A_DISPUTE = "ns:gov:rep:has:dispute";
bytes32 public constant NS_GOVERNANCE_REPORTING_FINALIZATION = "ns:gov:rep:has:finalized";
bytes32 public constant NS_GOVERNANCE_REPORTING_WITNESS_NO = "ns:gov:rep:witness:no";
bytes32 public constant NS_GOVERNANCE_REPORTING_STAKE_OWNED_YES = "ns:gov:rep:stake:owned:yes";
bytes32 public constant NS_GOVERNANCE_REPORTING_STAKE_OWNED_NO = "ns:gov:rep:stake:owned:no";
bytes32 public constant NS_GOVERNANCE_REPORTING_BURN_RATE = "ns:gov:rep:burn:rate";
bytes32 public constant NS_GOVERNANCE_REPORTER_COMMISSION = "ns:gov:reporter:commission";
bytes32 public constant NS_CLAIM_PERIOD = "ns:claim:period";
bytes32 public constant NS_CLAIM_PAYOUTS = "ns:claim:payouts";
bytes32 public constant NS_CLAIM_BEGIN_TS = "ns:claim:begin:ts";
bytes32 public constant NS_CLAIM_EXPIRY_TS = "ns:claim:expiry:ts";
bytes32 public constant NS_RESOLUTION_DEADLINE = "ns:resolution:deadline";
bytes32 public constant NS_RESOLUTION_COOL_DOWN_PERIOD = "ns:resolution:cdp";
bytes32 public constant NS_COVER_PLATFORM_FEE = "ns:cover:platform:fee";
bytes32 public constant NS_CLAIM_REPORTER_COMMISSION = "ns:claim:reporter:commission";
bytes32 public constant NS_LAST_LIQUIDITY_STATE_UPDATE = "ns:last:snl:update";
bytes32 public constant NS_LIQUIDITY_STATE_UPDATE_INTERVAL = "ns:snl:update:interval";
bytes32 public constant NS_LENDING_STRATEGY_ACTIVE = "ns:lending:strategy:active";
bytes32 public constant NS_LENDING_STRATEGY_DISABLED = "ns:lending:strategy:disabled";
bytes32 public constant NS_LENDING_STRATEGY_WITHDRAWAL_START = "ns:lending:strategy:w:start";
bytes32 public constant NS_ACCRUAL_INVOCATION = "ns:accrual:invocation";
bytes32 public constant NS_LENDING_STRATEGY_WITHDRAWAL_END = "ns:lending:strategy:w:end";
bytes32 public constant CNAME_PROTOCOL = "Neptune Mutual Protocol";
bytes32 public constant CNAME_TREASURY = "Treasury";
bytes32 public constant CNAME_POLICY = "Policy";
bytes32 public constant CNAME_POLICY_ADMIN = "Policy Admin";
bytes32 public constant CNAME_BOND_POOL = "BondPool";
bytes32 public constant CNAME_STAKING_POOL = "Staking Pool";
bytes32 public constant CNAME_CLAIMS_PROCESSOR = "Claims Processor";
bytes32 public constant CNAME_COVER = "Cover";
bytes32 public constant CNAME_GOVERNANCE = "Governance";
bytes32 public constant CNAME_RESOLUTION = "Resolution";
bytes32 public constant CNAME_VAULT_FACTORY = "Vault Factory";
bytes32 public constant CNAME_CXTOKEN_FACTORY = "cxToken Factory";
bytes32 public constant CNAME_COVER_STAKE = "Cover Stake";
bytes32 public constant CNAME_COVER_REASSURANCE = "Cover Reassurance";
bytes32 public constant CNAME_LIQUIDITY_VAULT = "Vault";
bytes32 public constant CNAME_VAULT_DELEGATE = "Vault Delegate";
bytes32 public constant CNAME_LIQUIDITY_ENGINE = "Liquidity Engine";
function getProtocolInternal(IStore s) external view returns (IProtocol) {
return IProtocol(getProtocolAddressInternal(s));
}
function getProtocolAddressInternal(IStore s) public view returns (address) {
return s.getAddressByKey(CNS_CORE);
}
function getContractInternal(
IStore s,
bytes32 name,
bytes32 key
) public view returns (address) {
if (key > 0) {
return s.getAddressByKeys(NS_CONTRACTS, name, key);
}
return s.getAddressByKeys(NS_CONTRACTS, name);
}
function isProtocolMemberInternal(IStore s, address contractAddress) public view returns (bool) {
return s.getBoolByKeys(ProtoUtilV1.NS_MEMBERS, contractAddress);
}
function mustBeProtocolMember(IStore s, address contractAddress) external view {
bool isMember = isProtocolMemberInternal(s, contractAddress);
require(isMember, "Not a protocol member");
}
function mustBeExactContract(
IStore s,
bytes32 name,
bytes32 key,
address sender
) public view {
address contractAddress = getContractInternal(s, name, key);
require(sender == contractAddress, "Access denied");
}
function senderMustBeExactContract(IStore s, bytes32 name) external view {
return callerMustBeExactContract(s, name, msg.sender);
}
function callerMustBeExactContract(
IStore s,
bytes32 name,
address caller
) public view {
return mustBeExactContract(s, name, ProtoUtilV1.KEY_INTENTIONALLY_EMPTY, caller);
}
function getNpmTokenInstanceInternal(IStore s) external view returns (IERC20) {
return IERC20(getNpmTokenAddressInternal(s));
}
function getNpmTokenAddressInternal(IStore s) public view returns (address) {
address npm = s.getAddressByKey(CNS_NPM);
return npm;
}
function getUniswapV2RouterInternal(IStore s) external view returns (address) {
return s.getAddressByKey(CNS_UNISWAP_V2_ROUTER);
}
function getUniswapV2FactoryInternal(IStore s) external view returns (address) {
return s.getAddressByKey(CNS_UNISWAP_V2_FACTORY);
}
function getNpmPriceOracleInternal(IStore s) external view returns (address) {
return s.getAddressByKey(CNS_NPM_PRICE_ORACLE);
}
function getTreasuryAddressInternal(IStore s) external view returns (address) {
return s.getAddressByKey(CNS_TREASURY);
}
function getStablecoinAddressInternal(IStore s) public view returns (address) {
return s.getAddressByKey(CNS_COVER_STABLECOIN);
}
function getStablecoinPrecisionInternal(IStore s) external view returns (uint256) {
return 10**IERC20Detailed(getStablecoinAddressInternal(s)).decimals();
}
function getBurnAddressInternal(IStore s) external view returns (address) {
return s.getAddressByKey(CNS_BURNER);
}
}
文件 42 的 54:Recoverable.sol
pragma solidity ^0.8.0;
import "openzeppelin-solidity/contracts/security/ReentrancyGuard.sol";
import "../interfaces/IRecoverable.sol";
import "../libraries/BaseLibV1.sol";
import "../libraries/ValidationLibV1.sol";
abstract contract Recoverable is ReentrancyGuard, IRecoverable {
using ValidationLibV1 for IStore;
IStore public override s;
constructor(IStore store) {
require(address(store) != address(0), "Invalid Store");
s = store;
}
function recoverEther(address sendTo) external override nonReentrant {
s.mustNotBePaused();
AccessControlLibV1.mustBeRecoveryAgent(s);
BaseLibV1.recoverEtherInternal(sendTo);
}
function recoverToken(address token, address sendTo) external override nonReentrant {
s.mustNotBePaused();
AccessControlLibV1.mustBeRecoveryAgent(s);
BaseLibV1.recoverTokenInternal(token, sendTo);
}
}
文件 43 的 54:ReentrancyGuard.sol
pragma solidity ^0.8.0;
abstract contract ReentrancyGuard {
uint256 private constant _NOT_ENTERED = 1;
uint256 private constant _ENTERED = 2;
uint256 private _status;
constructor() {
_status = _NOT_ENTERED;
}
modifier nonReentrant() {
require(_status != _ENTERED, "ReentrancyGuard: reentrant call");
_status = _ENTERED;
_;
_status = _NOT_ENTERED;
}
}
文件 44 的 54:RegistryLibV1.sol
pragma solidity ^0.8.0;
import "./ProtoUtilV1.sol";
import "./StoreKeyUtil.sol";
import "../interfaces/ICover.sol";
import "../interfaces/IPolicy.sol";
import "../interfaces/IBondPool.sol";
import "../interfaces/ICoverStake.sol";
import "../interfaces/ICxTokenFactory.sol";
import "../interfaces/ICoverReassurance.sol";
import "../interfaces/IGovernance.sol";
import "../interfaces/IVault.sol";
import "../interfaces/IVaultFactory.sol";
library RegistryLibV1 {
using ProtoUtilV1 for IStore;
using StoreKeyUtil for IStore;
function getGovernanceContract(IStore s) external view returns (IGovernance) {
return IGovernance(s.getContractInternal(ProtoUtilV1.CNS_GOVERNANCE, ProtoUtilV1.KEY_INTENTIONALLY_EMPTY));
}
function getResolutionContract(IStore s) external view returns (IGovernance) {
return IGovernance(s.getContractInternal(ProtoUtilV1.CNS_GOVERNANCE_RESOLUTION, ProtoUtilV1.KEY_INTENTIONALLY_EMPTY));
}
function getStakingContract(IStore s) external view returns (ICoverStake) {
return ICoverStake(s.getContractInternal(ProtoUtilV1.CNS_COVER_STAKE, ProtoUtilV1.KEY_INTENTIONALLY_EMPTY));
}
function getCxTokenFactory(IStore s) external view returns (ICxTokenFactory) {
return ICxTokenFactory(s.getContractInternal(ProtoUtilV1.CNS_COVER_CXTOKEN_FACTORY, ProtoUtilV1.KEY_INTENTIONALLY_EMPTY));
}
function getPolicyContract(IStore s) external view returns (IPolicy) {
return IPolicy(s.getContractInternal(ProtoUtilV1.CNS_COVER_POLICY, ProtoUtilV1.KEY_INTENTIONALLY_EMPTY));
}
function getReassuranceContract(IStore s) external view returns (ICoverReassurance) {
return ICoverReassurance(s.getContractInternal(ProtoUtilV1.CNS_COVER_REASSURANCE, ProtoUtilV1.KEY_INTENTIONALLY_EMPTY));
}
function getBondPoolContract(IStore s) external view returns (IBondPool) {
return IBondPool(getBondPoolAddress(s));
}
function getProtocolContract(IStore s, bytes32 cns) public view returns (address) {
return s.getAddressByKeys(ProtoUtilV1.NS_CONTRACTS, cns);
}
function getProtocolContract(
IStore s,
bytes32 cns,
bytes32 key
) public view returns (address) {
return s.getAddressByKeys(ProtoUtilV1.NS_CONTRACTS, cns, key);
}
function getCoverContract(IStore s) external view returns (ICover) {
address vault = getProtocolContract(s, ProtoUtilV1.CNS_COVER);
return ICover(vault);
}
function getVault(IStore s, bytes32 coverKey) external view returns (IVault) {
return IVault(getVaultAddress(s, coverKey));
}
function getVaultAddress(IStore s, bytes32 coverKey) public view returns (address) {
address vault = getProtocolContract(s, ProtoUtilV1.CNS_COVER_VAULT, coverKey);
return vault;
}
function getVaultDelegate(IStore s) external view returns (address) {
address vaultImplementation = getProtocolContract(s, ProtoUtilV1.CNS_COVER_VAULT_DELEGATE);
return vaultImplementation;
}
function getStakingPoolAddress(IStore s) external view returns (address) {
address pool = getProtocolContract(s, ProtoUtilV1.CNS_STAKING_POOL);
return pool;
}
function getBondPoolAddress(IStore s) public view returns (address) {
address pool = getProtocolContract(s, ProtoUtilV1.CNS_BOND_POOL);
return pool;
}
function getVaultFactoryContract(IStore s) external view returns (IVaultFactory) {
address factory = s.getContractInternal(ProtoUtilV1.CNS_COVER_VAULT_FACTORY, ProtoUtilV1.KEY_INTENTIONALLY_EMPTY);
return IVaultFactory(factory);
}
}
文件 45 的 54:RoutineInvokerLibV1.sol
pragma solidity ^0.8.0;
import "openzeppelin-solidity/contracts/token/ERC20/IERC20.sol";
import "../interfaces/IStore.sol";
import "../interfaces/ILendingStrategy.sol";
import "./PriceLibV1.sol";
import "./CoverUtilV1.sol";
library RoutineInvokerLibV1 {
using CoverUtilV1 for IStore;
using PriceLibV1 for IStore;
using ProtoUtilV1 for IStore;
using RegistryLibV1 for IStore;
using StoreKeyUtil for IStore;
using StrategyLibV1 for IStore;
enum Action {
Deposit,
Withdraw
}
function updateStateAndLiquidityInternal(IStore s, bytes32 coverKey) external {
_invoke(s, coverKey);
}
function _invoke(IStore s, bytes32 coverKey) private {
if (s.getLastUpdatedOnInternal(coverKey) + _getUpdateInterval(s) > block.timestamp) {
return;
}
PriceLibV1.setNpmPrice(s);
if (coverKey > 0) {
_updateWithdrawalPeriod(s, coverKey);
_invokeAssetManagement(s, coverKey);
s.setLastUpdatedOnInternal(coverKey);
}
}
function _getUpdateInterval(IStore s) private view returns (uint256) {
return s.getUintByKey(ProtoUtilV1.NS_LIQUIDITY_STATE_UPDATE_INTERVAL);
}
function getWithdrawalInfoInternal(IStore s, bytes32 coverKey)
public
view
returns (
bool isWithdrawalPeriod,
uint256 lendingPeriod,
uint256 withdrawalWindow,
uint256 start,
uint256 end
)
{
(lendingPeriod, withdrawalWindow) = s.getRiskPoolingPeriodsInternal(coverKey);
start = s.getUintByKey(getNextWithdrawalStartKeyInternal(coverKey));
end = s.getUintByKey(getNextWithdrawalEndKeyInternal(coverKey));
if (block.timestamp >= start && block.timestamp <= end) {
isWithdrawalPeriod = true;
}
}
function _isWithdrawalPeriod(IStore s, bytes32 coverKey) private view returns (bool) {
(bool isWithdrawalPeriod, , , , ) = getWithdrawalInfoInternal(s, coverKey);
return isWithdrawalPeriod;
}
function _updateWithdrawalPeriod(IStore s, bytes32 coverKey) private {
(, uint256 lendingPeriod, uint256 withdrawalWindow, uint256 start, uint256 end) = getWithdrawalInfoInternal(s, coverKey);
if (lendingPeriod == 0 || withdrawalWindow == 0) {
return;
}
if (block.timestamp > end) {
start = block.timestamp + lendingPeriod;
end = start + withdrawalWindow;
s.setUintByKey(getNextWithdrawalStartKeyInternal(coverKey), start);
s.setUintByKey(getNextWithdrawalEndKeyInternal(coverKey), end);
setAccrualCompleteInternal(s, coverKey, false);
}
}
function isAccrualCompleteInternal(IStore s, bytes32 coverKey) external view returns (bool) {
return s.getBoolByKey(getAccrualInvocationKeyInternal(coverKey));
}
function setAccrualCompleteInternal(
IStore s,
bytes32 coverKey,
bool flag
) public {
s.setBoolByKey(getAccrualInvocationKeyInternal(coverKey), flag);
}
function getAccrualInvocationKeyInternal(bytes32 coverKey) public pure returns (bytes32) {
return keccak256(abi.encodePacked(ProtoUtilV1.NS_ACCRUAL_INVOCATION, coverKey));
}
function getNextWithdrawalStartKeyInternal(bytes32 coverKey) public pure returns (bytes32) {
return keccak256(abi.encodePacked(ProtoUtilV1.NS_LENDING_STRATEGY_WITHDRAWAL_START, coverKey));
}
function getNextWithdrawalEndKeyInternal(bytes32 coverKey) public pure returns (bytes32) {
return keccak256(abi.encodePacked(ProtoUtilV1.NS_LENDING_STRATEGY_WITHDRAWAL_END, coverKey));
}
function mustBeDuringWithdrawalPeriod(IStore s, bytes32 coverKey) external view {
uint256 start = s.getUintByKey(getNextWithdrawalStartKeyInternal(coverKey));
uint256 end = s.getUintByKey(getNextWithdrawalEndKeyInternal(coverKey));
require(start > 0 && block.timestamp >= start, "Withdrawal period has not started");
require(end > 0 && block.timestamp <= end, "Withdrawal period has already ended");
}
function _executeAndGetAction(
IStore s,
ILendingStrategy,
bytes32 coverKey
) private returns (Action) {
bool isNormal = s.isCoverNormalInternal(coverKey);
if (isNormal != true) {
s.setUintByKey(getNextWithdrawalStartKeyInternal(coverKey), 0);
s.setUintByKey(getNextWithdrawalEndKeyInternal(coverKey), 0);
return Action.Withdraw;
}
if (_isWithdrawalPeriod(s, coverKey) == true) {
return Action.Withdraw;
}
return Action.Deposit;
}
function _canDeposit(
IStore s,
ILendingStrategy strategy,
uint256 totalStrategies,
bytes32 coverKey
) private view returns (uint256) {
IERC20 stablecoin = IERC20(s.getStablecoinAddressInternal());
uint256 totalBalance = s.getStablecoinOwnedByVaultInternal(coverKey);
uint256 maximumAllowed = (totalBalance * s.getMaxLendingRatioInternal()) / ProtoUtilV1.MULTIPLIER;
uint256 allocation = maximumAllowed / totalStrategies;
uint256 weight = strategy.getWeight();
uint256 canDeposit = (allocation * weight) / ProtoUtilV1.MULTIPLIER;
uint256 alreadyDeposited = s.getAmountInStrategyInternal(coverKey, strategy.getName(), address(stablecoin));
if (alreadyDeposited >= canDeposit) {
return 0;
}
return canDeposit - alreadyDeposited;
}
function _invokeAssetManagement(IStore s, bytes32 coverKey) private {
address vault = s.getVaultAddress(coverKey);
_withdrawFromDisabled(s, coverKey, vault);
address[] memory strategies = s.getActiveStrategiesInternal();
for (uint256 i = 0; i < strategies.length; i++) {
ILendingStrategy strategy = ILendingStrategy(strategies[i]);
_executeStrategy(s, strategy, strategies.length, vault, coverKey);
}
}
function _executeStrategy(
IStore s,
ILendingStrategy strategy,
uint256 totalStrategies,
address vault,
bytes32 coverKey
) private {
uint256 canDeposit = _canDeposit(s, strategy, totalStrategies, coverKey);
uint256 balance = IERC20(s.getStablecoinAddressInternal()).balanceOf(vault);
if (canDeposit > balance) {
canDeposit = balance;
}
Action action = _executeAndGetAction(s, strategy, coverKey);
if (action == Action.Deposit && canDeposit == 0) {
return;
}
if (action == Action.Withdraw) {
_withdrawAllFromStrategy(strategy, vault, coverKey);
return;
}
_depositToStrategy(strategy, coverKey, canDeposit);
}
function _depositToStrategy(
ILendingStrategy strategy,
bytes32 coverKey,
uint256 amount
) private {
strategy.deposit(coverKey, amount);
}
function _withdrawAllFromStrategy(
ILendingStrategy strategy,
address vault,
bytes32 coverKey
) private returns (uint256 stablecoinWithdrawn) {
uint256 balance = IERC20(strategy.getDepositCertificate()).balanceOf(vault);
if (balance > 0) {
stablecoinWithdrawn = strategy.withdraw(coverKey);
}
}
function _withdrawFromDisabled(
IStore s,
bytes32 coverKey,
address onBehalfOf
) private {
address[] memory strategies = s.getDisabledStrategiesInternal();
for (uint256 i = 0; i < strategies.length; i++) {
ILendingStrategy strategy = ILendingStrategy(strategies[i]);
uint256 balance = IERC20(strategy.getDepositCertificate()).balanceOf(onBehalfOf);
if (balance > 0) {
strategy.withdraw(coverKey);
}
}
}
}
文件 46 的 54: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");
}
}
}
文件 47 的 54:StoreKeyUtil.sol
pragma solidity ^0.8.0;
import "../interfaces/IStore.sol";
library StoreKeyUtil {
function setUintByKey(
IStore s,
bytes32 key,
uint256 value
) external {
require(key > 0, "Invalid key");
return s.setUint(key, value);
}
function setUintByKeys(
IStore s,
bytes32 key1,
bytes32 key2,
uint256 value
) external {
return s.setUint(_getKey(key1, key2), value);
}
function setUintByKeys(
IStore s,
bytes32 key1,
bytes32 key2,
bytes32 key3,
uint256 value
) external {
return s.setUint(_getKey(key1, key2, key3), value);
}
function setUintByKeys(
IStore s,
bytes32 key1,
bytes32 key2,
address account,
uint256 value
) external {
return s.setUint(_getKey(key1, key2, account), value);
}
function addUintByKey(
IStore s,
bytes32 key,
uint256 value
) external {
require(key > 0, "Invalid key");
return s.addUint(key, value);
}
function addUintByKeys(
IStore s,
bytes32 key1,
bytes32 key2,
uint256 value
) external {
return s.addUint(_getKey(key1, key2), value);
}
function addUintByKeys(
IStore s,
bytes32 key1,
bytes32 key2,
address account,
uint256 value
) external {
return s.addUint(_getKey(key1, key2, account), value);
}
function subtractUintByKey(
IStore s,
bytes32 key,
uint256 value
) external {
require(key > 0, "Invalid key");
return s.subtractUint(key, value);
}
function subtractUintByKeys(
IStore s,
bytes32 key1,
bytes32 key2,
uint256 value
) external {
return s.subtractUint(_getKey(key1, key2), value);
}
function subtractUintByKeys(
IStore s,
bytes32 key1,
bytes32 key2,
address account,
uint256 value
) external {
return s.subtractUint(_getKey(key1, key2, account), value);
}
function setStringByKey(
IStore s,
bytes32 key,
string calldata value
) external {
require(key > 0, "Invalid key");
s.setString(key, value);
}
function setStringByKeys(
IStore s,
bytes32 key1,
bytes32 key2,
string calldata value
) external {
return s.setString(_getKey(key1, key2), value);
}
function setStringByKeys(
IStore s,
bytes32 key1,
bytes32 key2,
bytes32 key3,
string calldata value
) external {
return s.setString(_getKey(key1, key2, key3), value);
}
function setBytes32ByKey(
IStore s,
bytes32 key,
bytes32 value
) external {
require(key > 0, "Invalid key");
s.setBytes32(key, value);
}
function setBytes32ByKeys(
IStore s,
bytes32 key1,
bytes32 key2,
bytes32 value
) external {
return s.setBytes32(_getKey(key1, key2), value);
}
function setBytes32ByKeys(
IStore s,
bytes32 key1,
bytes32 key2,
bytes32 key3,
bytes32 value
) external {
return s.setBytes32(_getKey(key1, key2, key3), value);
}
function setBoolByKey(
IStore s,
bytes32 key,
bool value
) external {
require(key > 0, "Invalid key");
return s.setBool(key, value);
}
function setBoolByKeys(
IStore s,
bytes32 key1,
bytes32 key2,
bool value
) external {
return s.setBool(_getKey(key1, key2), value);
}
function setBoolByKeys(
IStore s,
bytes32 key1,
bytes32 key2,
bytes32 key3,
bool value
) external {
return s.setBool(_getKey(key1, key2, key3), value);
}
function setBoolByKeys(
IStore s,
bytes32 key,
address account,
bool value
) external {
return s.setBool(_getKey(key, account), value);
}
function setAddressByKey(
IStore s,
bytes32 key,
address value
) external {
require(key > 0, "Invalid key");
return s.setAddress(key, value);
}
function setAddressByKeys(
IStore s,
bytes32 key1,
bytes32 key2,
address value
) external {
return s.setAddress(_getKey(key1, key2), value);
}
function setAddressByKeys(
IStore s,
bytes32 key1,
bytes32 key2,
bytes32 key3,
address value
) external {
return s.setAddress(_getKey(key1, key2, key3), value);
}
function setAddressArrayByKey(
IStore s,
bytes32 key,
address value
) external {
require(key > 0, "Invalid key");
return s.setAddressArrayItem(key, value);
}
function setAddressArrayByKeys(
IStore s,
bytes32 key1,
bytes32 key2,
address value
) external {
return s.setAddressArrayItem(_getKey(key1, key2), value);
}
function setAddressArrayByKeys(
IStore s,
bytes32 key1,
bytes32 key2,
bytes32 key3,
address value
) external {
return s.setAddressArrayItem(_getKey(key1, key2, key3), value);
}
function setAddressBooleanByKey(
IStore s,
bytes32 key,
address account,
bool value
) external {
require(key > 0, "Invalid key");
return s.setAddressBoolean(key, account, value);
}
function setAddressBooleanByKeys(
IStore s,
bytes32 key1,
bytes32 key2,
address account,
bool value
) external {
return s.setAddressBoolean(_getKey(key1, key2), account, value);
}
function setAddressBooleanByKeys(
IStore s,
bytes32 key1,
bytes32 key2,
bytes32 key3,
address account,
bool value
) external {
return s.setAddressBoolean(_getKey(key1, key2, key3), account, value);
}
function deleteUintByKey(IStore s, bytes32 key) external {
require(key > 0, "Invalid key");
return s.deleteUint(key);
}
function deleteUintByKeys(
IStore s,
bytes32 key1,
bytes32 key2
) external {
return s.deleteUint(_getKey(key1, key2));
}
function deleteUintByKeys(
IStore s,
bytes32 key1,
bytes32 key2,
bytes32 key3
) external {
return s.deleteUint(_getKey(key1, key2, key3));
}
function deleteBytes32ByKey(IStore s, bytes32 key) external {
require(key > 0, "Invalid key");
s.deleteBytes32(key);
}
function deleteBytes32ByKeys(
IStore s,
bytes32 key1,
bytes32 key2
) external {
return s.deleteBytes32(_getKey(key1, key2));
}
function deleteBoolByKey(IStore s, bytes32 key) external {
require(key > 0, "Invalid key");
return s.deleteBool(key);
}
function deleteBoolByKeys(
IStore s,
bytes32 key1,
bytes32 key2
) external {
return s.deleteBool(_getKey(key1, key2));
}
function deleteBoolByKeys(
IStore s,
bytes32 key,
address account
) external {
return s.deleteBool(_getKey(key, account));
}
function deleteAddressByKey(IStore s, bytes32 key) external {
require(key > 0, "Invalid key");
return s.deleteAddress(key);
}
function deleteAddressByKeys(
IStore s,
bytes32 key1,
bytes32 key2
) external {
return s.deleteAddress(_getKey(key1, key2));
}
function deleteAddressByKeys(
IStore s,
bytes32 key1,
bytes32 key2,
bytes32 key3
) external {
return s.deleteAddress(_getKey(key1, key2, key3));
}
function deleteAddressArrayByKey(
IStore s,
bytes32 key,
address value
) external {
require(key > 0, "Invalid key");
return s.deleteAddressArrayItem(key, value);
}
function deleteAddressArrayByKeys(
IStore s,
bytes32 key1,
bytes32 key2,
address value
) external {
return s.deleteAddressArrayItem(_getKey(key1, key2), value);
}
function deleteAddressArrayByKeys(
IStore s,
bytes32 key1,
bytes32 key2,
bytes32 key3,
address value
) external {
return s.deleteAddressArrayItem(_getKey(key1, key2, key3), value);
}
function deleteAddressArrayByIndexByKey(
IStore s,
bytes32 key,
uint256 index
) external {
require(key > 0, "Invalid key");
return s.deleteAddressArrayItemByIndex(key, index);
}
function deleteAddressArrayByIndexByKeys(
IStore s,
bytes32 key1,
bytes32 key2,
uint256 index
) external {
return s.deleteAddressArrayItemByIndex(_getKey(key1, key2), index);
}
function deleteAddressArrayByIndexByKeys(
IStore s,
bytes32 key1,
bytes32 key2,
bytes32 key3,
uint256 index
) external {
return s.deleteAddressArrayItemByIndex(_getKey(key1, key2, key3), index);
}
function getUintByKey(IStore s, bytes32 key) external view returns (uint256) {
require(key > 0, "Invalid key");
return s.getUint(key);
}
function getUintByKeys(
IStore s,
bytes32 key1,
bytes32 key2
) external view returns (uint256) {
return s.getUint(_getKey(key1, key2));
}
function getUintByKeys(
IStore s,
bytes32 key1,
bytes32 key2,
bytes32 key3
) external view returns (uint256) {
return s.getUint(_getKey(key1, key2, key3));
}
function getUintByKeys(
IStore s,
bytes32 key1,
bytes32 key2,
address account
) external view returns (uint256) {
return s.getUint(_getKey(key1, key2, account));
}
function getStringByKey(IStore s, bytes32 key) external view returns (string memory) {
require(key > 0, "Invalid key");
return s.getString(key);
}
function getStringByKeys(
IStore s,
bytes32 key1,
bytes32 key2
) external view returns (string memory) {
return s.getString(_getKey(key1, key2));
}
function getBytes32ByKey(IStore s, bytes32 key) external view returns (bytes32) {
require(key > 0, "Invalid key");
return s.getBytes32(key);
}
function getBytes32ByKeys(
IStore s,
bytes32 key1,
bytes32 key2
) external view returns (bytes32) {
return s.getBytes32(_getKey(key1, key2));
}
function getBoolByKey(IStore s, bytes32 key) external view returns (bool) {
require(key > 0, "Invalid key");
return s.getBool(key);
}
function getBoolByKeys(
IStore s,
bytes32 key1,
bytes32 key2,
bytes32 key3
) external view returns (bool) {
return s.getBool(_getKey(key1, key2, key3));
}
function getBoolByKeys(
IStore s,
bytes32 key1,
bytes32 key2
) external view returns (bool) {
return s.getBool(_getKey(key1, key2));
}
function getBoolByKeys(
IStore s,
bytes32 key,
address account
) external view returns (bool) {
return s.getBool(_getKey(key, account));
}
function getAddressByKey(IStore s, bytes32 key) external view returns (address) {
require(key > 0, "Invalid key");
return s.getAddress(key);
}
function getAddressByKeys(
IStore s,
bytes32 key1,
bytes32 key2
) external view returns (address) {
return s.getAddress(_getKey(key1, key2));
}
function getAddressByKeys(
IStore s,
bytes32 key1,
bytes32 key2,
bytes32 key3
) external view returns (address) {
return s.getAddress(_getKey(key1, key2, key3));
}
function getAddressBooleanByKey(
IStore s,
bytes32 key,
address account
) external view returns (bool) {
require(key > 0, "Invalid key");
return s.getAddressBoolean(key, account);
}
function getAddressBooleanByKeys(
IStore s,
bytes32 key1,
bytes32 key2,
address account
) external view returns (bool) {
return s.getAddressBoolean(_getKey(key1, key2), account);
}
function getAddressBooleanByKeys(
IStore s,
bytes32 key1,
bytes32 key2,
bytes32 key3,
address account
) external view returns (bool) {
return s.getAddressBoolean(_getKey(key1, key2, key3), account);
}
function countAddressArrayByKey(IStore s, bytes32 key) external view returns (uint256) {
require(key > 0, "Invalid key");
return s.countAddressArrayItems(key);
}
function countAddressArrayByKeys(
IStore s,
bytes32 key1,
bytes32 key2
) external view returns (uint256) {
return s.countAddressArrayItems(_getKey(key1, key2));
}
function countAddressArrayByKeys(
IStore s,
bytes32 key1,
bytes32 key2,
bytes32 key3
) external view returns (uint256) {
return s.countAddressArrayItems(_getKey(key1, key2, key3));
}
function getAddressArrayByKey(IStore s, bytes32 key) external view returns (address[] memory) {
require(key > 0, "Invalid key");
return s.getAddressArray(key);
}
function getAddressArrayByKeys(
IStore s,
bytes32 key1,
bytes32 key2
) external view returns (address[] memory) {
return s.getAddressArray(_getKey(key1, key2));
}
function getAddressArrayByKeys(
IStore s,
bytes32 key1,
bytes32 key2,
bytes32 key3
) external view returns (address[] memory) {
return s.getAddressArray(_getKey(key1, key2, key3));
}
function getAddressArrayItemPositionByKey(
IStore s,
bytes32 key,
address addressToFind
) external view returns (uint256) {
require(key > 0, "Invalid key");
return s.getAddressArrayItemPosition(key, addressToFind);
}
function getAddressArrayItemPositionByKeys(
IStore s,
bytes32 key1,
bytes32 key2,
address addressToFind
) external view returns (uint256) {
return s.getAddressArrayItemPosition(_getKey(key1, key2), addressToFind);
}
function getAddressArrayItemPositionByKeys(
IStore s,
bytes32 key1,
bytes32 key2,
bytes32 key3,
address addressToFind
) external view returns (uint256) {
return s.getAddressArrayItemPosition(_getKey(key1, key2, key3), addressToFind);
}
function getAddressArrayItemByIndexByKey(
IStore s,
bytes32 key,
uint256 index
) external view returns (address) {
require(key > 0, "Invalid key");
return s.getAddressArrayItemByIndex(key, index);
}
function getAddressArrayItemByIndexByKeys(
IStore s,
bytes32 key1,
bytes32 key2,
uint256 index
) external view returns (address) {
return s.getAddressArrayItemByIndex(_getKey(key1, key2), index);
}
function getAddressArrayItemByIndexByKeys(
IStore s,
bytes32 key1,
bytes32 key2,
bytes32 key3,
uint256 index
) external view returns (address) {
return s.getAddressArrayItemByIndex(_getKey(key1, key2, key3), index);
}
function _getKey(bytes32 key1, bytes32 key2) private pure returns (bytes32) {
return keccak256(abi.encodePacked(key1, key2));
}
function _getKey(
bytes32 key1,
bytes32 key2,
bytes32 key3
) private pure returns (bytes32) {
return keccak256(abi.encodePacked(key1, key2, key3));
}
function _getKey(bytes32 key, address account) private pure returns (bytes32) {
return keccak256(abi.encodePacked(key, account));
}
function _getKey(
bytes32 key1,
bytes32 key2,
address account
) private pure returns (bytes32) {
return keccak256(abi.encodePacked(key1, key2, account));
}
function setBytes32ArrayByKey(
IStore s,
bytes32 key,
bytes32 value
) external {
require(key > 0, "Invalid key");
return s.setBytes32ArrayItem(key, value);
}
function setBytes32ArrayByKeys(
IStore s,
bytes32 key1,
bytes32 key2,
bytes32 value
) external {
return s.setBytes32ArrayItem(_getKey(key1, key2), value);
}
function setBytes32ArrayByKeys(
IStore s,
bytes32 key1,
bytes32 key2,
bytes32 key3,
bytes32 value
) external {
return s.setBytes32ArrayItem(_getKey(key1, key2, key3), value);
}
function deleteBytes32ArrayByKey(
IStore s,
bytes32 key,
bytes32 value
) external {
require(key > 0, "Invalid key");
return s.deleteBytes32ArrayItem(key, value);
}
function deleteBytes32ArrayByKeys(
IStore s,
bytes32 key1,
bytes32 key2,
bytes32 value
) external {
return s.deleteBytes32ArrayItem(_getKey(key1, key2), value);
}
function deleteBytes32ArrayByKeys(
IStore s,
bytes32 key1,
bytes32 key2,
bytes32 key3,
bytes32 value
) external {
return s.deleteBytes32ArrayItem(_getKey(key1, key2, key3), value);
}
function deleteBytes32ArrayByIndexByKey(
IStore s,
bytes32 key,
uint256 index
) external {
require(key > 0, "Invalid key");
return s.deleteBytes32ArrayItemByIndex(key, index);
}
function deleteBytes32ArrayByIndexByKeys(
IStore s,
bytes32 key1,
bytes32 key2,
uint256 index
) external {
return s.deleteBytes32ArrayItemByIndex(_getKey(key1, key2), index);
}
function deleteBytes32ArrayByIndexByKeys(
IStore s,
bytes32 key1,
bytes32 key2,
bytes32 key3,
uint256 index
) external {
return s.deleteBytes32ArrayItemByIndex(_getKey(key1, key2, key3), index);
}
function countBytes32ArrayByKey(IStore s, bytes32 key) external view returns (uint256) {
require(key > 0, "Invalid key");
return s.countBytes32ArrayItems(key);
}
function countBytes32ArrayByKeys(
IStore s,
bytes32 key1,
bytes32 key2
) external view returns (uint256) {
return s.countBytes32ArrayItems(_getKey(key1, key2));
}
function countBytes32ArrayByKeys(
IStore s,
bytes32 key1,
bytes32 key2,
bytes32 key3
) external view returns (uint256) {
return s.countBytes32ArrayItems(_getKey(key1, key2, key3));
}
function getBytes32ArrayByKey(IStore s, bytes32 key) external view returns (bytes32[] memory) {
require(key > 0, "Invalid key");
return s.getBytes32Array(key);
}
function getBytes32ArrayByKeys(
IStore s,
bytes32 key1,
bytes32 key2
) external view returns (bytes32[] memory) {
return s.getBytes32Array(_getKey(key1, key2));
}
function getBytes32ArrayByKeys(
IStore s,
bytes32 key1,
bytes32 key2,
bytes32 key3
) external view returns (bytes32[] memory) {
return s.getBytes32Array(_getKey(key1, key2, key3));
}
function getBytes32ArrayItemPositionByKey(
IStore s,
bytes32 key,
bytes32 bytes32ToFind
) external view returns (uint256) {
require(key > 0, "Invalid key");
return s.getBytes32ArrayItemPosition(key, bytes32ToFind);
}
function getBytes32ArrayItemPositionByKeys(
IStore s,
bytes32 key1,
bytes32 key2,
bytes32 bytes32ToFind
) external view returns (uint256) {
return s.getBytes32ArrayItemPosition(_getKey(key1, key2), bytes32ToFind);
}
function getBytes32ArrayItemPositionByKeys(
IStore s,
bytes32 key1,
bytes32 key2,
bytes32 key3,
bytes32 bytes32ToFind
) external view returns (uint256) {
return s.getBytes32ArrayItemPosition(_getKey(key1, key2, key3), bytes32ToFind);
}
function getBytes32ArrayItemByIndexByKey(
IStore s,
bytes32 key,
uint256 index
) external view returns (bytes32) {
require(key > 0, "Invalid key");
return s.getBytes32ArrayItemByIndex(key, index);
}
function getBytes32ArrayItemByIndexByKeys(
IStore s,
bytes32 key1,
bytes32 key2,
uint256 index
) external view returns (bytes32) {
return s.getBytes32ArrayItemByIndex(_getKey(key1, key2), index);
}
function getBytes32ArrayItemByIndexByKeys(
IStore s,
bytes32 key1,
bytes32 key2,
bytes32 key3,
uint256 index
) external view returns (bytes32) {
return s.getBytes32ArrayItemByIndex(_getKey(key1, key2, key3), index);
}
}
文件 48 的 54:StrategyLibV1.sol
pragma solidity ^0.8.0;
import "openzeppelin-solidity/contracts/token/ERC20/IERC20.sol";
import "../interfaces/IStore.sol";
import "../interfaces/ILendingStrategy.sol";
import "./PriceLibV1.sol";
import "./RegistryLibV1.sol";
library StrategyLibV1 {
using ProtoUtilV1 for IStore;
using StoreKeyUtil for IStore;
using RegistryLibV1 for IStore;
uint256 public constant DEFAULT_LENDING_PERIOD = 180 days;
uint256 public constant DEFAULT_WITHDRAWAL_WINDOW = 7 days;
event StrategyAdded(address indexed strategy);
event RiskPoolingPeriodSet(bytes32 indexed key, uint256 lendingPeriod, uint256 withdrawalWindow);
event MaxLendingRatioSet(uint256 ratio);
function _getIsActiveStrategyKey(address strategyAddress) private pure returns (bytes32) {
return keccak256(abi.encodePacked(ProtoUtilV1.NS_LENDING_STRATEGY_ACTIVE, strategyAddress));
}
function _getIsDisabledStrategyKey(address strategyAddress) private pure returns (bytes32) {
return keccak256(abi.encodePacked(ProtoUtilV1.NS_LENDING_STRATEGY_DISABLED, strategyAddress));
}
function disableStrategyInternal(IStore s, address toFind) external {
_disableStrategy(s, toFind);
s.setAddressArrayByKey(ProtoUtilV1.NS_LENDING_STRATEGY_DISABLED, toFind);
}
function deleteStrategyInternal(IStore s, address toFind) external {
_deleteStrategy(s, toFind);
}
function addStrategiesInternal(IStore s, address[] calldata strategies) external {
for (uint256 i = 0; i < strategies.length; i++) {
address strategy = strategies[i];
_addStrategy(s, strategy);
}
}
function getRiskPoolingPeriodsInternal(IStore s, bytes32 coverKey) external view returns (uint256 lendingPeriod, uint256 withdrawalWindow) {
lendingPeriod = s.getUintByKey(getLendingPeriodKeyInternal(coverKey));
withdrawalWindow = s.getUintByKey(getWithdrawalWindowKeyInternal(coverKey));
if (lendingPeriod == 0) {
lendingPeriod = s.getUintByKey(getLendingPeriodKeyInternal(0));
withdrawalWindow = s.getUintByKey(getWithdrawalWindowKeyInternal(0));
}
lendingPeriod = lendingPeriod == 0 ? DEFAULT_LENDING_PERIOD : lendingPeriod;
withdrawalWindow = withdrawalWindow == 0 ? DEFAULT_WITHDRAWAL_WINDOW : withdrawalWindow;
}
function setRiskPoolingPeriodsInternal(
IStore s,
bytes32 coverKey,
uint256 lendingPeriod,
uint256 withdrawalWindow
) external {
s.setUintByKey(getLendingPeriodKeyInternal(coverKey), lendingPeriod);
s.setUintByKey(getWithdrawalWindowKeyInternal(coverKey), withdrawalWindow);
emit RiskPoolingPeriodSet(coverKey, lendingPeriod, withdrawalWindow);
}
function getLendingPeriodKeyInternal(bytes32 coverKey) public pure returns (bytes32) {
if (coverKey > 0) {
return keccak256(abi.encodePacked(ProtoUtilV1.NS_COVER_LIQUIDITY_LENDING_PERIOD, coverKey));
}
return ProtoUtilV1.NS_COVER_LIQUIDITY_LENDING_PERIOD;
}
function getMaxLendingRatioInternal(IStore s) external view returns (uint256) {
return s.getUintByKey(getMaxLendingRatioKeyInternal());
}
function setMaxLendingRatioInternal(IStore s, uint256 ratio) external {
s.setUintByKey(getMaxLendingRatioKeyInternal(), ratio);
emit MaxLendingRatioSet(ratio);
}
function getMaxLendingRatioKeyInternal() public pure returns (bytes32) {
return ProtoUtilV1.NS_COVER_LIQUIDITY_MAX_LENDING_RATIO;
}
function getWithdrawalWindowKeyInternal(bytes32 coverKey) public pure returns (bytes32) {
if (coverKey > 0) {
return keccak256(abi.encodePacked(ProtoUtilV1.NS_COVER_LIQUIDITY_WITHDRAWAL_WINDOW, coverKey));
}
return ProtoUtilV1.NS_COVER_LIQUIDITY_WITHDRAWAL_WINDOW;
}
function _addStrategy(IStore s, address deployedOn) private {
ILendingStrategy strategy = ILendingStrategy(deployedOn);
require(strategy.getWeight() <= ProtoUtilV1.MULTIPLIER, "Weight too much");
s.setBoolByKey(_getIsActiveStrategyKey(deployedOn), true);
s.setAddressArrayByKey(ProtoUtilV1.NS_LENDING_STRATEGY_ACTIVE, deployedOn);
emit StrategyAdded(deployedOn);
}
function _disableStrategy(IStore s, address toFind) private {
bytes32 key = ProtoUtilV1.NS_LENDING_STRATEGY_ACTIVE;
uint256 pos = s.getAddressArrayItemPosition(key, toFind);
require(pos > 0, "Invalid strategy");
s.deleteAddressArrayItem(key, toFind);
s.setBoolByKey(_getIsActiveStrategyKey(toFind), false);
s.setBoolByKey(_getIsDisabledStrategyKey(toFind), true);
}
function _deleteStrategy(IStore s, address toFind) private {
bytes32 key = ProtoUtilV1.NS_LENDING_STRATEGY_DISABLED;
uint256 pos = s.getAddressArrayItemPosition(key, toFind);
require(pos > 0, "Invalid strategy");
s.deleteAddressArrayItem(key, toFind);
s.setBoolByKey(_getIsDisabledStrategyKey(toFind), false);
}
function getDisabledStrategiesInternal(IStore s) external view returns (address[] memory strategies) {
return s.getAddressArrayByKey(ProtoUtilV1.NS_LENDING_STRATEGY_DISABLED);
}
function getActiveStrategiesInternal(IStore s) external view returns (address[] memory strategies) {
return s.getAddressArrayByKey(ProtoUtilV1.NS_LENDING_STRATEGY_ACTIVE);
}
function getStrategyOutKeyInternal(bytes32 coverKey, address token) public pure returns (bytes32) {
return keccak256(abi.encodePacked(ProtoUtilV1.NS_VAULT_STRATEGY_OUT, coverKey, token));
}
function getSpecificStrategyOutKeyInternal(
bytes32 coverKey,
bytes32 strategyName,
address token
) public pure returns (bytes32) {
return keccak256(abi.encodePacked(ProtoUtilV1.NS_VAULT_STRATEGY_OUT, coverKey, strategyName, token));
}
function getAmountInStrategiesInternal(
IStore s,
bytes32 coverKey,
address token
) public view returns (uint256) {
bytes32 k = getStrategyOutKeyInternal(coverKey, token);
return s.getUintByKey(k);
}
function getAmountInStrategyInternal(
IStore s,
bytes32 coverKey,
bytes32 strategyName,
address token
) public view returns (uint256) {
bytes32 k = getSpecificStrategyOutKeyInternal(coverKey, strategyName, token);
return s.getUintByKey(k);
}
function preTransferToStrategyInternal(
IStore s,
IERC20 token,
bytes32 coverKey,
bytes32 strategyName,
uint256 amount
) external {
if (s.getStablecoinAddressInternal() != address(token)) {
return;
}
_addToStrategyOut(s, coverKey, address(token), amount);
_addToSpecificStrategyOut(s, coverKey, strategyName, address(token), amount);
}
function postReceiveFromStrategyInternal(
IStore s,
IERC20 token,
bytes32 coverKey,
bytes32 strategyName,
uint256 received
) external returns (uint256 income, uint256 loss) {
if (s.getStablecoinAddressInternal() != address(token)) {
return (income, loss);
}
uint256 amountInThisStrategy = getAmountInStrategyInternal(s, coverKey, strategyName, address(token));
income = received > amountInThisStrategy ? received - amountInThisStrategy : 0;
loss = received < amountInThisStrategy ? amountInThisStrategy - received : 0;
_reduceStrategyOut(s, coverKey, address(token), amountInThisStrategy);
_clearSpecificStrategyOut(s, coverKey, strategyName, address(token));
_logIncomes(s, coverKey, strategyName, income, loss);
}
function _addToStrategyOut(
IStore s,
bytes32 coverKey,
address token,
uint256 amountToAdd
) private {
bytes32 k = getStrategyOutKeyInternal(coverKey, token);
s.addUintByKey(k, amountToAdd);
}
function _reduceStrategyOut(
IStore s,
bytes32 coverKey,
address token,
uint256 amount
) private {
bytes32 k = getStrategyOutKeyInternal(coverKey, token);
s.subtractUintByKey(k, amount);
}
function _addToSpecificStrategyOut(
IStore s,
bytes32 coverKey,
bytes32 strategyName,
address token,
uint256 amountToAdd
) private {
bytes32 k = getSpecificStrategyOutKeyInternal(coverKey, strategyName, token);
s.addUintByKey(k, amountToAdd);
}
function _clearSpecificStrategyOut(
IStore s,
bytes32 coverKey,
bytes32 strategyName,
address token
) private {
bytes32 k = getSpecificStrategyOutKeyInternal(coverKey, strategyName, token);
s.deleteUintByKey(k);
}
function _logIncomes(
IStore s,
bytes32 coverKey,
bytes32 strategyName,
uint256 income,
uint256 loss
) private {
s.addUintByKey(ProtoUtilV1.NS_VAULT_LENDING_INCOMES, income);
s.addUintByKey(keccak256(abi.encodePacked(ProtoUtilV1.NS_VAULT_LENDING_INCOMES, coverKey)), income);
s.addUintByKey(keccak256(abi.encodePacked(ProtoUtilV1.NS_VAULT_LENDING_INCOMES, coverKey, strategyName)), income);
s.addUintByKey(ProtoUtilV1.NS_VAULT_LENDING_LOSSES, loss);
s.addUintByKey(keccak256(abi.encodePacked(ProtoUtilV1.NS_VAULT_LENDING_LOSSES, coverKey)), loss);
s.addUintByKey(keccak256(abi.encodePacked(ProtoUtilV1.NS_VAULT_LENDING_LOSSES, coverKey, strategyName)), loss);
}
function getStablecoinOwnedByVaultInternal(IStore s, bytes32 coverKey) external view returns (uint256) {
address stablecoin = s.getStablecoinAddressInternal();
uint256 balance = IERC20(stablecoin).balanceOf(s.getVaultAddress(coverKey));
uint256 inStrategies = getAmountInStrategiesInternal(s, coverKey, stablecoin);
return balance + inStrategies;
}
}
文件 49 的 54:ValidationLibV1.sol
pragma solidity ^0.8.0;
import "openzeppelin-solidity/contracts/token/ERC20/IERC20.sol";
import "openzeppelin-solidity/contracts/access/IAccessControl.sol";
import "../interfaces/IStore.sol";
import "../interfaces/IPausable.sol";
import "../interfaces/ICxToken.sol";
import "./GovernanceUtilV1.sol";
import "./AccessControlLibV1.sol";
library ValidationLibV1 {
using CoverUtilV1 for IStore;
using GovernanceUtilV1 for IStore;
using ProtoUtilV1 for IStore;
using RegistryLibV1 for IStore;
using StoreKeyUtil for IStore;
function mustNotBePaused(IStore s) public view {
address protocol = s.getProtocolAddressInternal();
require(IPausable(protocol).paused() == false, "Protocol is paused");
}
function mustEnsureAllProductsAreNormal(IStore s, bytes32 coverKey) external view {
require(s.getBoolByKeys(ProtoUtilV1.NS_COVER, coverKey), "Cover does not exist");
require(s.isCoverNormalInternal(coverKey) == true, "Status not normal");
}
function mustHaveNormalProductStatus(
IStore s,
bytes32 coverKey,
bytes32 productKey
) external view {
require(s.getBoolByKeys(ProtoUtilV1.NS_COVER, coverKey), "Cover does not exist");
require(s.getProductStatusInternal(coverKey, productKey) == CoverUtilV1.ProductStatus.Normal, "Status not normal");
}
function mustBeValidCoverKey(IStore s, bytes32 coverKey) external view {
require(s.getBoolByKeys(ProtoUtilV1.NS_COVER, coverKey), "Cover does not exist");
}
function mustSupportProducts(IStore s, bytes32 coverKey) external view {
require(s.supportsProductsInternal(coverKey), "Does not have products");
}
function mustBeValidProduct(
IStore s,
bytes32 coverKey,
bytes32 productKey
) public view {
require(s.isValidProductInternal(coverKey, productKey), "Product does not exist");
}
function mustBeActiveProduct(
IStore s,
bytes32 coverKey,
bytes32 productKey
) public view {
require(s.isActiveProductInternal(coverKey, productKey), "Product retired or deleted");
}
function mustBeCoverOwner(
IStore s,
bytes32 coverKey,
address sender
) public view {
bool isCoverOwner = s.getCoverOwnerInternal(coverKey) == sender;
require(isCoverOwner, "Forbidden");
}
function mustBeCoverOwnerOrCoverContract(
IStore s,
bytes32 coverKey,
address sender
) external view {
bool isCoverOwner = s.getCoverOwnerInternal(coverKey) == sender;
bool isCoverContract = address(s.getCoverContract()) == sender;
require(isCoverOwner || isCoverContract, "Forbidden");
}
function senderMustBeCoverOwnerOrAdmin(IStore s, bytes32 coverKey) external view {
if (AccessControlLibV1.hasAccessInternal(s, AccessControlLibV1.NS_ROLES_ADMIN, msg.sender) == false) {
mustBeCoverOwner(s, coverKey, msg.sender);
}
}
function senderMustBePolicyContract(IStore s) external view {
s.senderMustBeExactContract(ProtoUtilV1.CNS_COVER_POLICY);
}
function senderMustBePolicyManagerContract(IStore s) external view {
s.senderMustBeExactContract(ProtoUtilV1.CNS_COVER_POLICY_MANAGER);
}
function senderMustBeCoverContract(IStore s) external view {
s.senderMustBeExactContract(ProtoUtilV1.CNS_COVER);
}
function senderMustBeVaultContract(IStore s, bytes32 coverKey) external view {
address vault = s.getVaultAddress(coverKey);
require(msg.sender == vault, "Forbidden");
}
function senderMustBeGovernanceContract(IStore s) external view {
s.senderMustBeExactContract(ProtoUtilV1.CNS_GOVERNANCE);
}
function senderMustBeClaimsProcessorContract(IStore s) external view {
s.senderMustBeExactContract(ProtoUtilV1.CNS_CLAIM_PROCESSOR);
}
function callerMustBeClaimsProcessorContract(IStore s, address caller) external view {
s.callerMustBeExactContract(ProtoUtilV1.CNS_CLAIM_PROCESSOR, caller);
}
function senderMustBeStrategyContract(IStore s) external view {
bool senderIsStrategyContract = s.getBoolByKey(_getIsActiveStrategyKey(msg.sender));
require(senderIsStrategyContract == true, "Not a strategy contract");
}
function callerMustBeStrategyContract(IStore s, address caller) public view {
bool isActive = s.getBoolByKey(_getIsActiveStrategyKey(caller));
bool wasDisabled = s.getBoolByKey(_getIsDisabledStrategyKey(caller));
require(isActive == true || wasDisabled == true, "Not a strategy contract");
}
function callerMustBeSpecificStrategyContract(
IStore s,
address caller,
bytes32 strategyName
) external view {
callerMustBeStrategyContract(s, caller);
require(IMember(caller).getName() == strategyName, "Access denied");
}
function _getIsActiveStrategyKey(address strategyAddress) private pure returns (bytes32) {
return keccak256(abi.encodePacked(ProtoUtilV1.NS_LENDING_STRATEGY_ACTIVE, strategyAddress));
}
function _getIsDisabledStrategyKey(address strategyAddress) private pure returns (bytes32) {
return keccak256(abi.encodePacked(ProtoUtilV1.NS_LENDING_STRATEGY_DISABLED, strategyAddress));
}
function senderMustBeProtocolMember(IStore s) external view {
require(s.isProtocolMemberInternal(msg.sender), "Forbidden");
}
function mustBeReporting(
IStore s,
bytes32 coverKey,
bytes32 productKey
) external view {
require(s.getProductStatusInternal(coverKey, productKey) == CoverUtilV1.ProductStatus.IncidentHappened, "Not reporting");
}
function mustBeDisputed(
IStore s,
bytes32 coverKey,
bytes32 productKey
) external view {
require(s.getProductStatusInternal(coverKey, productKey) == CoverUtilV1.ProductStatus.FalseReporting, "Not disputed");
}
function mustBeClaimable(
IStore s,
bytes32 coverKey,
bytes32 productKey
) public view {
require(s.getProductStatusInternal(coverKey, productKey) == CoverUtilV1.ProductStatus.Claimable, "Not claimable");
}
function mustBeClaimingOrDisputed(
IStore s,
bytes32 coverKey,
bytes32 productKey
) external view {
CoverUtilV1.ProductStatus status = s.getProductStatusInternal(coverKey, productKey);
bool claiming = status == CoverUtilV1.ProductStatus.Claimable;
bool falseReporting = status == CoverUtilV1.ProductStatus.FalseReporting;
require(claiming || falseReporting, "Not claimable nor disputed");
}
function mustBeReportingOrDisputed(
IStore s,
bytes32 coverKey,
bytes32 productKey
) external view {
CoverUtilV1.ProductStatus status = s.getProductStatusInternal(coverKey, productKey);
bool incidentHappened = status == CoverUtilV1.ProductStatus.IncidentHappened;
bool falseReporting = status == CoverUtilV1.ProductStatus.FalseReporting;
require(incidentHappened || falseReporting, "Not reported nor disputed");
}
function mustBeBeforeResolutionDeadline(
IStore s,
bytes32 coverKey,
bytes32 productKey
) external view {
uint256 deadline = s.getResolutionDeadlineInternal(coverKey, productKey);
if (deadline > 0) {
require(block.timestamp < deadline, "Emergency resolution deadline over");
}
}
function mustNotHaveResolutionDeadline(
IStore s,
bytes32 coverKey,
bytes32 productKey
) external view {
uint256 deadline = s.getResolutionDeadlineInternal(coverKey, productKey);
require(deadline == 0, "Resolution already has deadline");
}
function mustBeAfterResolutionDeadline(
IStore s,
bytes32 coverKey,
bytes32 productKey
) public view {
uint256 deadline = s.getResolutionDeadlineInternal(coverKey, productKey);
require(deadline > 0 && block.timestamp >= deadline, "Still unresolved");
}
function mustBeAfterFinalization(
IStore s,
bytes32 coverKey,
bytes32 productKey,
uint256 incidentDate
) public view {
require(s.getBoolByKey(GovernanceUtilV1.getHasFinalizedKeyInternal(coverKey, productKey, incidentDate)), "Incident not finalized");
}
function mustBeValidIncidentDate(
IStore s,
bytes32 coverKey,
bytes32 productKey,
uint256 incidentDate
) public view {
require(s.getActiveIncidentDateInternal(coverKey, productKey) == incidentDate, "Invalid incident date");
}
function mustHaveDispute(
IStore s,
bytes32 coverKey,
bytes32 productKey
) external view {
bool hasDispute = s.getBoolByKey(GovernanceUtilV1.getHasDisputeKeyInternal(coverKey, productKey));
require(hasDispute == true, "Not disputed");
}
function mustNotHaveDispute(
IStore s,
bytes32 coverKey,
bytes32 productKey
) external view {
bool hasDispute = s.getBoolByKey(GovernanceUtilV1.getHasDisputeKeyInternal(coverKey, productKey));
require(hasDispute == false, "Already disputed");
}
function mustBeDuringReportingPeriod(
IStore s,
bytes32 coverKey,
bytes32 productKey
) external view {
require(s.getResolutionTimestampInternal(coverKey, productKey) >= block.timestamp, "Reporting window closed");
}
function mustBeAfterReportingPeriod(
IStore s,
bytes32 coverKey,
bytes32 productKey
) public view {
require(block.timestamp > s.getResolutionTimestampInternal(coverKey, productKey), "Reporting still active");
}
function mustBeValidCxToken(
IStore s,
bytes32 coverKey,
bytes32 productKey,
address cxToken,
uint256 incidentDate
) public view {
require(s.getBoolByKeys(ProtoUtilV1.NS_COVER_CXTOKEN, cxToken) == true, "Unknown cxToken");
bytes32 COVER_KEY = ICxToken(cxToken).COVER_KEY();
bytes32 PRODUCT_KEY = ICxToken(cxToken).PRODUCT_KEY();
require(coverKey == COVER_KEY && productKey == PRODUCT_KEY, "Invalid cxToken");
uint256 expires = ICxToken(cxToken).expiresOn();
require(expires > incidentDate, "Invalid or expired cxToken");
}
function mustBeValidClaim(
IStore s,
address account,
bytes32 coverKey,
bytes32 productKey,
address cxToken,
uint256 incidentDate,
uint256 amount
) external view {
mustBeSupportedProductOrEmpty(s, coverKey, productKey);
mustBeValidCxToken(s, coverKey, productKey, cxToken, incidentDate);
mustBeClaimable(s, coverKey, productKey);
mustBeValidIncidentDate(s, coverKey, productKey, incidentDate);
mustBeDuringClaimPeriod(s, coverKey, productKey);
require(ICxToken(cxToken).getClaimablePolicyOf(account) >= amount, "Claim exceeds your coverage");
}
function mustNotHaveUnstaken(
IStore s,
address account,
bytes32 coverKey,
bytes32 productKey,
uint256 incidentDate
) public view {
uint256 withdrawal = s.getReportingUnstakenAmountInternal(account, coverKey, productKey, incidentDate);
require(withdrawal == 0, "Already unstaken");
}
function validateUnstakeWithoutClaim(
IStore s,
bytes32 coverKey,
bytes32 productKey,
uint256 incidentDate
) external view {
mustNotBePaused(s);
mustBeSupportedProductOrEmpty(s, coverKey, productKey);
mustNotHaveUnstaken(s, msg.sender, coverKey, productKey, incidentDate);
mustBeAfterFinalization(s, coverKey, productKey, incidentDate);
}
function validateUnstakeWithClaim(
IStore s,
bytes32 coverKey,
bytes32 productKey,
uint256 incidentDate
) external view {
mustNotBePaused(s);
mustBeSupportedProductOrEmpty(s, coverKey, productKey);
mustNotHaveUnstaken(s, msg.sender, coverKey, productKey, incidentDate);
mustBeValidIncidentDate(s, coverKey, productKey, incidentDate);
mustBeAfterResolutionDeadline(s, coverKey, productKey);
}
function mustBeDuringClaimPeriod(
IStore s,
bytes32 coverKey,
bytes32 productKey
) public view {
uint256 beginsFrom = s.getUintByKeys(ProtoUtilV1.NS_CLAIM_BEGIN_TS, coverKey, productKey);
uint256 expiresAt = s.getUintByKeys(ProtoUtilV1.NS_CLAIM_EXPIRY_TS, coverKey, productKey);
require(beginsFrom > 0, "Invalid claim begin date");
require(expiresAt > beginsFrom, "Invalid claim period");
require(block.timestamp >= beginsFrom, "Claim period hasn't begun");
require(block.timestamp <= expiresAt, "Claim period has expired");
}
function mustBeAfterClaimExpiry(
IStore s,
bytes32 coverKey,
bytes32 productKey
) external view {
require(block.timestamp > s.getUintByKeys(ProtoUtilV1.NS_CLAIM_EXPIRY_TS, coverKey, productKey), "Claim still active");
}
function senderMustBeWhitelistedCoverCreator(IStore s) external view {
require(s.getAddressBooleanByKey(ProtoUtilV1.NS_COVER_CREATOR_WHITELIST, msg.sender), "Not whitelisted");
}
function senderMustBeWhitelistedIfRequired(
IStore s,
bytes32 coverKey,
bytes32 productKey,
address sender
) external view {
bool supportsProducts = s.supportsProductsInternal(coverKey);
bool required = supportsProducts ? s.checkIfProductRequiresWhitelistInternal(coverKey, productKey) : s.checkIfRequiresWhitelistInternal(coverKey);
if (required == false) {
return;
}
require(s.getAddressBooleanByKeys(ProtoUtilV1.NS_COVER_USER_WHITELIST, coverKey, productKey, sender), "You are not whitelisted");
}
function mustBeSupportedProductOrEmpty(
IStore s,
bytes32 coverKey,
bytes32 productKey
) public view {
bool hasProducts = s.supportsProductsInternal(coverKey);
hasProducts ? require(productKey > 0, "Specify a product") : require(productKey == 0, "Invalid product");
if (hasProducts) {
mustBeValidProduct(s, coverKey, productKey);
mustBeActiveProduct(s, coverKey, productKey);
}
}
function mustNotHavePolicyDisabled(
IStore s,
bytes32 coverKey,
bytes32 productKey
) external view {
require(!s.isPolicyDisabledInternal(coverKey, productKey), "Policy purchase disabled");
}
function mustMaintainStablecoinThreshold(IStore s, uint256 amount) external view {
uint256 stablecoinPrecision = s.getStablecoinPrecisionInternal();
require(amount >= ProtoUtilV1.MIN_LIQUIDITY * stablecoinPrecision, "Liquidity is below threshold");
require(amount <= ProtoUtilV1.MAX_LIQUIDITY * stablecoinPrecision, "Liquidity is above threshold");
}
function mustMaintainProposalThreshold(IStore s, uint256 amount) external view {
uint256 stablecoinPrecision = s.getStablecoinPrecisionInternal();
require(amount >= ProtoUtilV1.MIN_PROPOSAL_AMOUNT * stablecoinPrecision, "Proposal is below threshold");
require(amount <= ProtoUtilV1.MAX_PROPOSAL_AMOUNT * stablecoinPrecision, "Proposal is above threshold");
}
}
文件 50 的 54:Vault.sol
import "openzeppelin-solidity/contracts/token/ERC20/ERC20.sol";
import "openzeppelin-solidity/contracts/interfaces/IERC3156FlashLender.sol";
import "./WithFlashLoan.sol";
pragma solidity ^0.8.0;
contract Vault is WithFlashLoan {
using ProtoUtilV1 for IStore;
using RegistryLibV1 for IStore;
constructor(
IStore store,
bytes32 coverKey,
string memory tokenName,
string memory tokenSymbol,
IERC20 stablecoin
) VaultBase(store, coverKey, tokenName, tokenSymbol, stablecoin) {}
function getInfo(address you) external view override returns (VaultInfoType memory) {
return delegate().getInfoImplementation(key, you);
}
function version() external pure override returns (bytes32) {
return "v0.1";
}
function getName() external pure override returns (bytes32) {
return ProtoUtilV1.CNAME_LIQUIDITY_VAULT;
}
}
文件 51 的 54:VaultBase.sol
import "openzeppelin-solidity/contracts/token/ERC20/ERC20.sol";
import "../Recoverable.sol";
import "../../interfaces/IVaultDelegate.sol";
import "../../interfaces/IVault.sol";
import "../../libraries/NTransferUtilV2.sol";
pragma solidity ^0.8.0;
abstract contract VaultBase is ERC20, Recoverable, IVault {
using ProtoUtilV1 for IStore;
using RegistryLibV1 for IStore;
using NTransferUtilV2 for IERC20;
bytes32 public override key;
address public override sc;
constructor(
IStore store,
bytes32 coverKey,
string memory tokenName,
string memory tokenSymbol,
IERC20 stablecoin
) ERC20(tokenName, tokenSymbol) Recoverable(store) {
key = coverKey;
sc = address(stablecoin);
}
function delegate() public view returns (IVaultDelegate) {
return IVaultDelegate(s.getVaultDelegate());
}
}
文件 52 的 54:VaultLiquidity.sol
import "./VaultBase.sol";
pragma solidity ^0.8.0;
abstract contract VaultLiquidity is VaultBase {
using ProtoUtilV1 for IStore;
using RegistryLibV1 for IStore;
using NTransferUtilV2 for IERC20;
function transferGovernance(
bytes32 coverKey,
address to,
uint256 amount
) external override nonReentrant {
require(coverKey == key, "Forbidden");
require(amount > 0, "Please specify amount");
address stablecoin = delegate().preTransferGovernance(msg.sender, coverKey, to, amount);
IERC20(stablecoin).ensureTransfer(to, amount);
delegate().postTransferGovernance(msg.sender, coverKey, to, amount);
emit GovernanceTransfer(to, amount);
}
function addLiquidity(AddLiquidityArgs calldata args) external override nonReentrant {
require(args.coverKey == key, "Forbidden");
require(args.amount > 0, "Please specify amount");
(uint256 podsToMint, uint256 previousNpmStake) = delegate().preAddLiquidity(msg.sender, args.coverKey, args.amount, args.npmStakeToAdd);
require(podsToMint > 0, "Can't determine PODs");
IERC20(sc).ensureTransferFrom(msg.sender, address(this), args.amount);
if (args.npmStakeToAdd > 0) {
IERC20(s.getNpmTokenAddressInternal()).ensureTransferFrom(msg.sender, address(this), args.npmStakeToAdd);
}
super._mint(msg.sender, podsToMint);
delegate().postAddLiquidity(msg.sender, args.coverKey, args.amount, args.npmStakeToAdd);
emit PodsIssued(msg.sender, podsToMint, args.amount, args.referralCode);
if (previousNpmStake == 0) {
emit Entered(args.coverKey, msg.sender);
}
emit NpmStaken(msg.sender, args.npmStakeToAdd);
}
function removeLiquidity(
bytes32 coverKey,
uint256 podsToRedeem,
uint256 npmStakeToRemove,
bool exit
) external override nonReentrant {
require(coverKey == key, "Forbidden");
require(podsToRedeem > 0 || npmStakeToRemove > 0, "Please specify amount");
(address stablecoin, uint256 stablecoinToRelease) = delegate().preRemoveLiquidity(msg.sender, coverKey, podsToRedeem, npmStakeToRemove, exit);
if (podsToRedeem > 0) {
IERC20(address(this)).ensureTransferFrom(msg.sender, address(this), podsToRedeem);
IERC20(stablecoin).ensureTransfer(msg.sender, stablecoinToRelease);
}
super._burn(address(this), podsToRedeem);
if (npmStakeToRemove > 0) {
IERC20(s.getNpmTokenAddressInternal()).ensureTransfer(msg.sender, npmStakeToRemove);
}
delegate().postRemoveLiquidity(msg.sender, coverKey, podsToRedeem, npmStakeToRemove, exit);
emit PodsRedeemed(msg.sender, podsToRedeem, stablecoinToRelease);
if (exit) {
emit Exited(coverKey, msg.sender);
}
if (npmStakeToRemove > 0) {
emit NpmUnstaken(msg.sender, npmStakeToRemove);
}
}
function calculatePods(uint256 forStablecoinUnits) external view override returns (uint256) {
return delegate().calculatePodsImplementation(key, forStablecoinUnits);
}
function calculateLiquidity(uint256 podsToBurn) external view override returns (uint256) {
return delegate().calculateLiquidityImplementation(key, podsToBurn);
}
function getStablecoinBalanceOf() external view override returns (uint256) {
return delegate().getStablecoinBalanceOfImplementation(key);
}
function accrueInterest() external override nonReentrant {
delegate().accrueInterestImplementation(msg.sender, key);
emit InterestAccrued(key);
}
}
文件 53 的 54:VaultStrategy.sol
import "./VaultLiquidity.sol";
pragma solidity ^0.8.0;
abstract contract VaultStrategy is VaultLiquidity {
using ProtoUtilV1 for IStore;
using RegistryLibV1 for IStore;
using NTransferUtilV2 for IERC20;
uint256 private _transferToStrategyEntry = 0;
uint256 private _receiveFromStrategyEntry = 0;
function transferToStrategy(
IERC20 token,
bytes32 coverKey,
bytes32 strategyName,
uint256 amount
) external override {
require(address(token) != address(0), "Invalid token to transfer");
require(coverKey == key, "Forbidden");
require(strategyName > 0, "Invalid strategy");
require(amount > 0, "Please specify amount");
require(_transferToStrategyEntry == 0, "Access is denied");
_transferToStrategyEntry = 1;
delegate().preTransferToStrategy(msg.sender, token, coverKey, strategyName, amount);
token.ensureTransfer(msg.sender, amount);
delegate().postTransferToStrategy(msg.sender, token, coverKey, strategyName, amount);
emit StrategyTransfer(address(token), msg.sender, strategyName, amount);
_transferToStrategyEntry = 0;
}
function receiveFromStrategy(
IERC20 token,
bytes32 coverKey,
bytes32 strategyName,
uint256 amount
) external override {
require(coverKey == key, "Forbidden");
require(_receiveFromStrategyEntry == 0, "Access is denied");
require(amount > 0, "Please specify amount");
_receiveFromStrategyEntry = 1;
delegate().preReceiveFromStrategy(msg.sender, token, coverKey, strategyName, amount);
token.ensureTransferFrom(msg.sender, address(this), amount);
(uint256 income, uint256 loss) = delegate().postReceiveFromStrategy(msg.sender, token, coverKey, strategyName, amount);
emit StrategyReceipt(address(token), msg.sender, strategyName, amount, income, loss);
_receiveFromStrategyEntry = 0;
}
}
文件 54 的 54:WithFlashLoan.sol
pragma solidity ^0.8.0;
import "openzeppelin-solidity/contracts/token/ERC20/ERC20.sol";
import "openzeppelin-solidity/contracts/interfaces/IERC3156FlashLender.sol";
import "./VaultStrategy.sol";
abstract contract WithFlashLoan is VaultStrategy, IERC3156FlashLender {
using ProtoUtilV1 for IStore;
using RegistryLibV1 for IStore;
using NTransferUtilV2 for IERC20;
function flashLoan(
IERC3156FlashBorrower receiver,
address token,
uint256 amount,
bytes calldata data
) external override nonReentrant returns (bool) {
require(amount > 0, "Please specify amount");
(IERC20 stablecoin, uint256 fee, uint256 protocolFee) = delegate().preFlashLoan(msg.sender, key, receiver, token, amount, data);
uint256 previousBalance = stablecoin.balanceOf(address(this));
stablecoin.ensureTransfer(address(receiver), amount);
require(receiver.onFlashLoan(msg.sender, token, amount, fee, data) == keccak256("ERC3156FlashBorrower.onFlashLoan"), "IERC3156: Callback failed");
stablecoin.ensureTransferFrom(address(receiver), address(this), amount + fee);
uint256 finalBalance = stablecoin.balanceOf(address(this));
require(finalBalance >= previousBalance + fee, "Access is denied");
stablecoin.ensureTransfer(s.getTreasuryAddressInternal(), protocolFee);
delegate().postFlashLoan(msg.sender, key, receiver, token, amount, data);
emit FlashLoanBorrowed(address(this), address(receiver), token, amount, fee);
return true;
}
function flashFee(address token, uint256 amount) external view override returns (uint256) {
return delegate().getFlashFee(msg.sender, key, token, amount);
}
function maxFlashLoan(address token) external view override returns (uint256) {
return delegate().getMaxFlashLoan(msg.sender, key, token);
}
}
{
"compilationTarget": {
"contracts/core/liquidity/Vault.sol": "Vault"
},
"evmVersion": "london",
"libraries": {
"contracts/libraries/AccessControlLibV1.sol:AccessControlLibV1": "0x405848de6da43460c73341bc27b1aee3abf428ee",
"contracts/libraries/BaseLibV1.sol:BaseLibV1": "0x3def8f7843d024e9ef03d9db81626393d04f1c38",
"contracts/libraries/NTransferUtilV2.sol:NTransferUtilV2": "0xe29e2b025f9e3049dd257b17d4759d6bef83b8ab",
"contracts/libraries/ProtoUtilV1.sol:ProtoUtilV1": "0x1693cc00b92a8be4d2cfb8c87f5a134cd71c9de3",
"contracts/libraries/RegistryLibV1.sol:RegistryLibV1": "0x5dcc4142a09411f203526497af1cbe27a9922ab4",
"contracts/libraries/ValidationLibV1.sol:ValidationLibV1": "0x2736f310069457abcb6f4173fc2eb48c4679caf0"
},
"metadata": {
"bytecodeHash": "ipfs"
},
"optimizer": {
"enabled": true,
"runs": 999999
},
"remappings": []
}
[{"inputs":[{"internalType":"contract IStore","name":"store","type":"address"},{"internalType":"bytes32","name":"coverKey","type":"bytes32"},{"internalType":"string","name":"tokenName","type":"string"},{"internalType":"string","name":"tokenSymbol","type":"string"},{"internalType":"contract IERC20","name":"stablecoin","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":"bytes32","name":"coverKey","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"}],"name":"Entered","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"coverKey","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"}],"name":"Exited","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"lender","type":"address"},{"indexed":true,"internalType":"address","name":"borrower","type":"address"},{"indexed":true,"internalType":"address","name":"stablecoin","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"fee","type":"uint256"}],"name":"FlashLoanBorrowed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"GovernanceTransfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"coverKey","type":"bytes32"}],"name":"InterestAccrued","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"NpmStaken","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"NpmUnstaken","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"issued","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"liquidityAdded","type":"uint256"},{"indexed":true,"internalType":"bytes32","name":"referralCode","type":"bytes32"}],"name":"PodsIssued","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"redeemed","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"liquidityReleased","type":"uint256"}],"name":"PodsRedeemed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"token","type":"address"},{"indexed":true,"internalType":"address","name":"strategy","type":"address"},{"indexed":true,"internalType":"bytes32","name":"name","type":"bytes32"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"income","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"loss","type":"uint256"}],"name":"StrategyReceipt","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"token","type":"address"},{"indexed":true,"internalType":"address","name":"strategy","type":"address"},{"indexed":true,"internalType":"bytes32","name":"name","type":"bytes32"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"StrategyTransfer","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":"accrueInterest","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"bytes32","name":"coverKey","type":"bytes32"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"npmStakeToAdd","type":"uint256"},{"internalType":"bytes32","name":"referralCode","type":"bytes32"}],"internalType":"struct IVault.AddLiquidityArgs","name":"args","type":"tuple"}],"name":"addLiquidity","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":"uint256","name":"podsToBurn","type":"uint256"}],"name":"calculateLiquidity","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"forStablecoinUnits","type":"uint256"}],"name":"calculatePods","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":"delegate","outputs":[{"internalType":"contract IVaultDelegate","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"flashFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IERC3156FlashBorrower","name":"receiver","type":"address"},{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"flashLoan","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"you","type":"address"}],"name":"getInfo","outputs":[{"components":[{"internalType":"uint256","name":"totalPods","type":"uint256"},{"internalType":"uint256","name":"balance","type":"uint256"},{"internalType":"uint256","name":"extendedBalance","type":"uint256"},{"internalType":"uint256","name":"totalReassurance","type":"uint256"},{"internalType":"uint256","name":"myPodBalance","type":"uint256"},{"internalType":"uint256","name":"myShare","type":"uint256"},{"internalType":"uint256","name":"withdrawalOpen","type":"uint256"},{"internalType":"uint256","name":"withdrawalClose","type":"uint256"}],"internalType":"struct IVault.VaultInfoType","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getName","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"getStablecoinBalanceOf","outputs":[{"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":[],"name":"key","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"maxFlashLoan","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IERC20","name":"token","type":"address"},{"internalType":"bytes32","name":"coverKey","type":"bytes32"},{"internalType":"bytes32","name":"strategyName","type":"bytes32"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"receiveFromStrategy","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"sendTo","type":"address"}],"name":"recoverEther","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"address","name":"sendTo","type":"address"}],"name":"recoverToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"coverKey","type":"bytes32"},{"internalType":"uint256","name":"podsToRedeem","type":"uint256"},{"internalType":"uint256","name":"npmStakeToRemove","type":"uint256"},{"internalType":"bool","name":"exit","type":"bool"}],"name":"removeLiquidity","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"s","outputs":[{"internalType":"contract IStore","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"sc","outputs":[{"internalType":"address","name":"","type":"address"}],"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":"bytes32","name":"coverKey","type":"bytes32"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transferGovernance","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IERC20","name":"token","type":"address"},{"internalType":"bytes32","name":"coverKey","type":"bytes32"},{"internalType":"bytes32","name":"strategyName","type":"bytes32"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transferToStrategy","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"version","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"pure","type":"function"}]