// SPDX-License-Identifier: GPL-3.0-onlypragmasolidity >=0.5.0;interfaceIClaimsReward{
/// @dev Decides the next course of action for a given claim.functionchangeClaimStatus(uint claimid) external;
functiongetCurrencyAssetAddress(bytes4 currency) externalviewreturns (address);
functiongetRewardToBeGiven(uint check,
uint voteid,
uint flag
)
externalviewreturns (uint tokenCalculated,
bool lastClaimedCheck,
uint tokens,
uint perc
);
functionupgrade(address _newAdd) external;
functiongetRewardToBeDistributedByUser(address _add) externalviewreturns (uint total);
functiongetRewardAndClaimedStatus(uint check, uint claimId) externalviewreturns (uint reward, bool claimed);
functionclaimAllPendingReward(uint records) external;
functiongetAllPendingRewardOfUser(address _add) externalviewreturns (uint);
functionunlockCoverNote(uint coverId) external;
}
Contract Source Code
File 2 of 15: IERC20.sol
pragmasolidity ^0.5.0;/**
* @dev Interface of the ERC20 standard as defined in the EIP. Does not include
* the optional functions; to access them see {ERC20Detailed}.
*/interfaceIERC20{
/**
* @dev Returns the amount of tokens in existence.
*/functiontotalSupply() externalviewreturns (uint256);
/**
* @dev Returns the amount of tokens owned by `account`.
*/functionbalanceOf(address account) externalviewreturns (uint256);
/**
* @dev Moves `amount` tokens from the caller's account to `recipient`.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/functiontransfer(address recipient, uint256 amount) externalreturns (bool);
/**
* @dev Returns the remaining number of tokens that `spender` will be
* allowed to spend on behalf of `owner` through {transferFrom}. This is
* zero by default.
*
* This value changes when {approve} or {transferFrom} are called.
*/functionallowance(address owner, address spender) externalviewreturns (uint256);
/**
* @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* IMPORTANT: Beware that changing an allowance with this method brings the risk
* that someone may use both the old and the new allowance by unfortunate
* transaction ordering. One possible solution to mitigate this race
* condition is to first reduce the spender's allowance to 0 and set the
* desired value afterwards:
* https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
*
* Emits an {Approval} event.
*/functionapprove(address spender, uint256 amount) externalreturns (bool);
/**
* @dev Moves `amount` tokens from `sender` to `recipient` using the
* allowance mechanism. `amount` is then deducted from the caller's
* allowance.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/functiontransferFrom(address sender, address recipient, uint256 amount) externalreturns (bool);
/**
* @dev Emitted when `value` tokens are moved from one account (`from`) to
* another (`to`).
*
* Note that `value` may be zero.
*/eventTransfer(addressindexedfrom, addressindexed to, uint256 value);
/**
* @dev Emitted when the allowance of a `spender` for an `owner` is set by
* a call to {approve}. `value` is the new allowance.
*/eventApproval(addressindexed owner, addressindexed spender, uint256 value);
}
// SPDX-License-Identifier: GPL-3.0-onlypragmasolidity ^0.5.0;import"../interfaces/INXMMaster.sol";
contractMasterAware{
INXMMaster public master;
modifieronlyMember{
require(master.isMember(msg.sender), "Caller is not a member");
_;
}
modifieronlyInternal{
require(master.isInternal(msg.sender), "Caller is not an internal contract");
_;
}
modifieronlyMaster{
if (address(master) !=address(0)) {
require(address(master) ==msg.sender, "Not master");
}
_;
}
modifieronlyGovernance{
require(
master.checkIsAuthToGoverned(msg.sender),
"Caller is not authorized to govern"
);
_;
}
modifierwhenPaused{
require(master.isPause(), "System is not paused");
_;
}
modifierwhenNotPaused{
require(!master.isPause(), "System is paused");
_;
}
functionchangeDependentContractAddress() external;
functionchangeMasterAddress(address masterAddress) publiconlyMaster{
master = INXMMaster(masterAddress);
}
}
Contract Source Code
File 13 of 15: Quotation.sol
// SPDX-License-Identifier: GPL-3.0-onlypragmasolidity ^0.5.0;import"@openzeppelin/contracts/math/SafeMath.sol";
import"@openzeppelin/contracts/token/ERC20/IERC20.sol";
import"@openzeppelin/contracts/utils/ReentrancyGuard.sol";
import"../../abstract/MasterAware.sol";
import"../../interfaces/IClaimsReward.sol";
import"../../interfaces/IIncidents.sol";
import"../../interfaces/IPool.sol";
import"../../interfaces/IPooledStaking.sol";
import"../../interfaces/IQuotation.sol";
import"../../interfaces/IQuotationData.sol";
import"../../interfaces/ITokenController.sol";
import"../../interfaces/ITokenData.sol";
contractQuotationisIQuotation, MasterAware, ReentrancyGuard{
usingSafeMathforuint;
IClaimsReward public cr;
IPool public pool;
IPooledStaking public pooledStaking;
IQuotationData public qd;
ITokenController public tc;
ITokenData public td;
IIncidents public incidents;
/**
* @dev Iupgradable Interface to update dependent contract address
*/functionchangeDependentContractAddress() publiconlyInternal{
cr = IClaimsReward(master.getLatestAddress("CR"));
pool = IPool(master.getLatestAddress("P1"));
pooledStaking = IPooledStaking(master.getLatestAddress("PS"));
qd = IQuotationData(master.getLatestAddress("QD"));
tc = ITokenController(master.getLatestAddress("TC"));
td = ITokenData(master.getLatestAddress("TD"));
incidents = IIncidents(master.getLatestAddress("IC"));
}
// solhint-disable-next-line no-empty-blocksfunctionsendEther() publicpayable{}
/**
* @dev Expires a cover after a set period of time and changes the status of the cover
* @dev Reduces the total and contract sum assured
* @param coverId Cover Id.
*/functionexpireCover(uint coverId) external{
uint expirationDate = qd.getValidityOfCover(coverId);
require(expirationDate <now, "Quotation: cover is not due to expire");
uint coverStatus = qd.getCoverStatusNo(coverId);
require(coverStatus !=uint(IQuotationData.CoverStatus.CoverExpired), "Quotation: cover already expired");
(/* claim count */, bool hasOpenClaim, /* accepted */) = tc.coverInfo(coverId);
require(!hasOpenClaim, "Quotation: cover has an open claim");
if (coverStatus !=uint(IQuotationData.CoverStatus.ClaimAccepted)) {
(,, address contractAddress, bytes4 currency, uint amount,) = qd.getCoverDetailsByCoverID1(coverId);
qd.subFromTotalSumAssured(currency, amount);
qd.subFromTotalSumAssuredSC(contractAddress, currency, amount);
}
qd.changeCoverStatusNo(coverId, uint8(IQuotationData.CoverStatus.CoverExpired));
}
functionwithdrawCoverNote(address coverOwner, uint[] calldata coverIds, uint[] calldata reasonIndexes) external{
uint gracePeriod = tc.claimSubmissionGracePeriod();
for (uint i =0; i < coverIds.length; i++) {
uint expirationDate = qd.getValidityOfCover(coverIds[i]);
require(expirationDate.add(gracePeriod) <now, "Quotation: cannot withdraw before grace period expiration");
}
tc.withdrawCoverNote(coverOwner, coverIds, reasonIndexes);
}
functiongetWithdrawableCoverNoteCoverIds(address coverOwner
) publicviewreturns (uint[] memory expiredCoverIds,
bytes32[] memory lockReasons
) {
uint[] memory coverIds = qd.getAllCoversOfUser(coverOwner);
uint[] memory expiredIdsQueue =newuint[](coverIds.length);
uint gracePeriod = tc.claimSubmissionGracePeriod();
uint expiredQueueLength =0;
for (uint i =0; i < coverIds.length; i++) {
uint coverExpirationDate = qd.getValidityOfCover(coverIds[i]);
uint gracePeriodExpirationDate = coverExpirationDate.add(gracePeriod);
(/* claimCount */, bool hasOpenClaim, /* hasAcceptedClaim */) = tc.coverInfo(coverIds[i]);
if (!hasOpenClaim && gracePeriodExpirationDate <now) {
expiredIdsQueue[expiredQueueLength] = coverIds[i];
expiredQueueLength++;
}
}
expiredCoverIds =newuint[](expiredQueueLength);
lockReasons =newbytes32[](expiredQueueLength);
for (uint i =0; i < expiredQueueLength; i++) {
expiredCoverIds[i] = expiredIdsQueue[i];
lockReasons[i] =keccak256(abi.encodePacked("CN", coverOwner, expiredIdsQueue[i]));
}
}
functiongetWithdrawableCoverNotesAmount(address coverOwner) externalviewreturns (uint) {
uint withdrawableAmount;
bytes32[] memory lockReasons;
(/*expiredCoverIds*/, lockReasons) = getWithdrawableCoverNoteCoverIds(coverOwner);
for (uint i =0; i < lockReasons.length; i++) {
uint coverNoteAmount = tc.tokensLocked(coverOwner, lockReasons[i]);
withdrawableAmount = withdrawableAmount.add(coverNoteAmount);
}
return withdrawableAmount;
}
/**
* @dev Makes Cover funded via NXM tokens.
* @param smartCAdd Smart Contract Address
*/functionmakeCoverUsingNXMTokens(uint[] calldata coverDetails,
uint16 coverPeriod,
bytes4 coverCurr,
address smartCAdd,
uint8 _v,
bytes32 _r,
bytes32 _s
) externalonlyMemberwhenNotPaused{
tc.burnFrom(msg.sender, coverDetails[2]); // needs allowance
_verifyCoverDetails(msg.sender, smartCAdd, coverCurr, coverDetails, coverPeriod, _v, _r, _s, true);
}
/**
* @dev Verifies cover details signed off chain.
* @param from address of funder.
* @param scAddress Smart Contract Address
*/functionverifyCoverDetails(addresspayablefrom,
address scAddress,
bytes4 coverCurr,
uint[] memory coverDetails,
uint16 coverPeriod,
uint8 _v,
bytes32 _r,
bytes32 _s
) publiconlyInternal{
_verifyCoverDetails(
from,
scAddress,
coverCurr,
coverDetails,
coverPeriod,
_v,
_r,
_s,
false
);
}
/**
* @dev Verifies signature.
* @param coverDetails details related to cover.
* @param coverPeriod validity of cover.
* @param contractAddress smart contract address.
* @param _v argument from vrs hash.
* @param _r argument from vrs hash.
* @param _s argument from vrs hash.
*/functionverifySignature(uint[] memory coverDetails,
uint16 coverPeriod,
bytes4 currency,
address contractAddress,
uint8 _v,
bytes32 _r,
bytes32 _s
) publicviewreturns (bool) {
require(contractAddress !=address(0));
bytes32 hash = getOrderHash(coverDetails, coverPeriod, currency, contractAddress);
return isValidSignature(hash, _v, _r, _s);
}
/**
* @dev Gets order hash for given cover details.
* @param coverDetails details realted to cover.
* @param coverPeriod validity of cover.
* @param contractAddress smart contract address.
*/functiongetOrderHash(uint[] memory coverDetails,
uint16 coverPeriod,
bytes4 currency,
address contractAddress
) publicviewreturns (bytes32) {
returnkeccak256(
abi.encodePacked(
coverDetails[0],
currency,
coverPeriod,
contractAddress,
coverDetails[1],
coverDetails[2],
coverDetails[3],
coverDetails[4],
address(this)
)
);
}
/**
* @dev Verifies signature.
* @param hash order hash
* @param v argument from vrs hash.
* @param r argument from vrs hash.
* @param s argument from vrs hash.
*/functionisValidSignature(bytes32 hash, uint8 v, bytes32 r, bytes32 s) publicviewreturns (bool) {
bytesmemory prefix ="\x19Ethereum Signed Message:\n32";
bytes32 prefixedHash =keccak256(abi.encodePacked(prefix, hash));
address a =ecrecover(prefixedHash, v, r, s);
return (a == qd.getAuthQuoteEngine());
}
/**
* @dev Creates cover of the quotation, changes the status of the quotation ,
* updates the total sum assured and locks the tokens of the cover against a quote.
* @param from Quote member Ethereum address.
*/function_makeCover(//solhint-disable-lineaddresspayablefrom,
address contractAddress,
bytes4 coverCurrency,
uint[] memory coverDetails,
uint16 coverPeriod
) internal{
address underlyingToken = incidents.underlyingToken(contractAddress);
if (underlyingToken !=address(0)) {
address coverAsset = cr.getCurrencyAssetAddress(coverCurrency);
require(coverAsset == underlyingToken, "Quotation: Unsupported cover asset for this product");
}
uint cid = qd.getCoverLength();
qd.addCover(
coverPeriod,
coverDetails[0],
from,
coverCurrency,
contractAddress,
coverDetails[1],
coverDetails[2]
);
uint coverNoteAmount = coverDetails[2].mul(qd.tokensRetained()).div(100);
uint gracePeriod = tc.claimSubmissionGracePeriod();
uint claimSubmissionPeriod =uint(coverPeriod).mul(1days).add(gracePeriod);
bytes32 reason =keccak256(abi.encodePacked("CN", from, cid));
// mint and lock cover note
td.setDepositCNAmount(cid, coverNoteAmount);
tc.mintCoverNote(from, reason, coverNoteAmount, claimSubmissionPeriod);
qd.addInTotalSumAssured(coverCurrency, coverDetails[0]);
qd.addInTotalSumAssuredSC(contractAddress, coverCurrency, coverDetails[0]);
uint coverPremiumInNXM = coverDetails[2];
uint stakersRewardPercentage = td.stakerCommissionPer();
uint rewardValue = coverPremiumInNXM.mul(stakersRewardPercentage).div(100);
pooledStaking.accumulateReward(contractAddress, rewardValue);
}
/**
* @dev Makes a cover.
* @param from address of funder.
* @param scAddress Smart Contract Address
*/function_verifyCoverDetails(addresspayablefrom,
address scAddress,
bytes4 coverCurr,
uint[] memory coverDetails,
uint16 coverPeriod,
uint8 _v,
bytes32 _r,
bytes32 _s,
bool isNXM
) internal{
require(coverDetails[3] >now, "Quotation: Quote has expired");
require(coverPeriod >=30&& coverPeriod <=365, "Quotation: Cover period out of bounds");
require(!qd.timestampRepeated(coverDetails[4]), "Quotation: Quote already used");
qd.setTimestampRepeated(coverDetails[4]);
address asset = cr.getCurrencyAssetAddress(coverCurr);
if (coverCurr !="ETH"&&!isNXM) {
pool.transferAssetFrom(asset, from, coverDetails[1]);
}
require(verifySignature(coverDetails, coverPeriod, coverCurr, scAddress, _v, _r, _s), "Quotation: signature mismatch");
_makeCover(from, scAddress, coverCurr, coverDetails, coverPeriod);
}
functioncreateCover(addresspayablefrom,
address scAddress,
bytes4 currency,
uint[] calldata coverDetails,
uint16 coverPeriod,
uint8 _v,
bytes32 _r,
bytes32 _s
) externalonlyInternal{
require(coverDetails[3] >now, "Quotation: Quote has expired");
require(coverPeriod >=30&& coverPeriod <=365, "Quotation: Cover period out of bounds");
require(!qd.timestampRepeated(coverDetails[4]), "Quotation: Quote already used");
qd.setTimestampRepeated(coverDetails[4]);
require(verifySignature(coverDetails, coverPeriod, currency, scAddress, _v, _r, _s), "Quotation: signature mismatch");
_makeCover(from, scAddress, currency, coverDetails, coverPeriod);
}
// referenced in master, keeping for now// solhint-disable-next-line no-empty-blocksfunctiontransferAssetsToNewContract(address) externalpure{}
functionfreeUpHeldCovers() externalnonReentrant{
IERC20 dai = IERC20(cr.getCurrencyAssetAddress("DAI"));
uint membershipFee = td.joiningFee();
uint lastCoverId =106;
for (uint id =1; id <= lastCoverId; id++) {
if (qd.holdedCoverIDStatus(id) !=uint(IQuotationData.HCIDStatus.kycPending)) {
continue;
}
(/*id*/, /*sc*/, bytes4 currency, /*period*/) = qd.getHoldedCoverDetailsByID1(id);
(/*id*/, addresspayable userAddress, uint[] memory coverDetails) = qd.getHoldedCoverDetailsByID2(id);
uint refundedETH = membershipFee;
uint coverPremium = coverDetails[1];
if (qd.refundEligible(userAddress)) {
qd.setRefundEligible(userAddress, false);
}
qd.setHoldedCoverIDStatus(id, uint(IQuotationData.HCIDStatus.kycFailedOrRefunded));
if (currency =="ETH") {
refundedETH = refundedETH.add(coverPremium);
} else {
require(dai.transfer(userAddress, coverPremium), "Quotation: DAI refund transfer failed");
}
userAddress.transfer(refundedETH);
}
}
}
Contract Source Code
File 14 of 15: ReentrancyGuard.sol
pragmasolidity ^0.5.0;/**
* @dev Contract module that helps prevent reentrant calls to a function.
*
* Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier
* available, which can be applied to functions to make sure there are no nested
* (reentrant) calls to them.
*
* Note that because there is a single `nonReentrant` guard, functions marked as
* `nonReentrant` may not call one another. This can be worked around by making
* those functions `private`, and then adding `external` `nonReentrant` entry
* points to them.
*
* TIP: If you would like to learn more about reentrancy and alternative ways
* to protect against it, check out our blog post
* https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].
*
* _Since v2.5.0:_ this module is now much more gas efficient, given net gas
* metering changes introduced in the Istanbul hardfork.
*/contractReentrancyGuard{
boolprivate _notEntered;
constructor () internal{
// Storing an initial non-zero value makes deployment a bit more// expensive, but in exchange the refund on every call to nonReentrant// will be lower in amount. Since refunds are capped to a percetange of// the total transaction's gas, it is best to keep them low in cases// like this one, to increase the likelihood of the full refund coming// into effect.
_notEntered =true;
}
/**
* @dev Prevents a contract from calling itself, directly or indirectly.
* Calling a `nonReentrant` function from another `nonReentrant`
* function is not supported. It is possible to prevent this from happening
* by making the `nonReentrant` function external, and make it call a
* `private` function that does the actual work.
*/modifiernonReentrant() {
// On the first call to nonReentrant, _notEntered will be truerequire(_notEntered, "ReentrancyGuard: reentrant call");
// Any calls to nonReentrant after this point will fail
_notEntered =false;
_;
// By storing the original value once again, a refund is triggered (see// https://eips.ethereum.org/EIPS/eip-2200)
_notEntered =true;
}
}
Contract Source Code
File 15 of 15: SafeMath.sol
pragmasolidity ^0.5.0;/**
* @dev Wrappers over Solidity's arithmetic operations with added overflow
* checks.
*
* Arithmetic operations in Solidity wrap on overflow. This can easily result
* in bugs, because programmers usually assume that an overflow raises an
* error, which is the standard behavior in high level programming languages.
* `SafeMath` restores this intuition by reverting the transaction when an
* operation overflows.
*
* Using this library instead of the unchecked operations eliminates an entire
* class of bugs, so it's recommended to use it always.
*/librarySafeMath{
/**
* @dev Returns the addition of two unsigned integers, reverting on
* overflow.
*
* Counterpart to Solidity's `+` operator.
*
* Requirements:
* - Addition cannot overflow.
*/functionadd(uint256 a, uint256 b) internalpurereturns (uint256) {
uint256 c = a + b;
require(c >= a, "SafeMath: addition overflow");
return c;
}
/**
* @dev Returns the subtraction of two unsigned integers, reverting on
* overflow (when the result is negative).
*
* Counterpart to Solidity's `-` operator.
*
* Requirements:
* - Subtraction cannot overflow.
*/functionsub(uint256 a, uint256 b) internalpurereturns (uint256) {
return sub(a, b, "SafeMath: subtraction overflow");
}
/**
* @dev Returns the subtraction of two unsigned integers, reverting with custom message on
* overflow (when the result is negative).
*
* Counterpart to Solidity's `-` operator.
*
* Requirements:
* - Subtraction cannot overflow.
*
* _Available since v2.4.0._
*/functionsub(uint256 a, uint256 b, stringmemory errorMessage) internalpurereturns (uint256) {
require(b <= a, errorMessage);
uint256 c = a - b;
return c;
}
/**
* @dev Returns the multiplication of two unsigned integers, reverting on
* overflow.
*
* Counterpart to Solidity's `*` operator.
*
* Requirements:
* - Multiplication cannot overflow.
*/functionmul(uint256 a, uint256 b) internalpurereturns (uint256) {
// Gas optimization: this is cheaper than requiring 'a' not being zero, but the// benefit is lost if 'b' is also tested.// See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522if (a ==0) {
return0;
}
uint256 c = a * b;
require(c / a == b, "SafeMath: multiplication overflow");
return c;
}
/**
* @dev Returns the integer division of two unsigned integers. Reverts on
* division by zero. The result is rounded towards zero.
*
* Counterpart to Solidity's `/` operator. Note: this function uses a
* `revert` opcode (which leaves remaining gas untouched) while Solidity
* uses an invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
* - The divisor cannot be zero.
*/functiondiv(uint256 a, uint256 b) internalpurereturns (uint256) {
return div(a, b, "SafeMath: division by zero");
}
/**
* @dev Returns the integer division of two unsigned integers. Reverts with custom message on
* division by zero. The result is rounded towards zero.
*
* Counterpart to Solidity's `/` operator. Note: this function uses a
* `revert` opcode (which leaves remaining gas untouched) while Solidity
* uses an invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
* - The divisor cannot be zero.
*
* _Available since v2.4.0._
*/functiondiv(uint256 a, uint256 b, stringmemory errorMessage) internalpurereturns (uint256) {
// Solidity only automatically asserts when dividing by 0require(b >0, errorMessage);
uint256 c = a / b;
// assert(a == b * c + a % b); // There is no case in which this doesn't holdreturn c;
}
/**
* @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
* Reverts when dividing by zero.
*
* Counterpart to Solidity's `%` operator. This function uses a `revert`
* opcode (which leaves remaining gas untouched) while Solidity uses an
* invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
* - The divisor cannot be zero.
*/functionmod(uint256 a, uint256 b) internalpurereturns (uint256) {
return mod(a, b, "SafeMath: modulo by zero");
}
/**
* @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
* Reverts with custom message when dividing by zero.
*
* Counterpart to Solidity's `%` operator. This function uses a `revert`
* opcode (which leaves remaining gas untouched) while Solidity uses an
* invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
* - The divisor cannot be zero.
*
* _Available since v2.4.0._
*/functionmod(uint256 a, uint256 b, stringmemory errorMessage) internalpurereturns (uint256) {
require(b !=0, errorMessage);
return a % b;
}
}