Skip to content

Commit

Permalink
Merge pull request #73 from etherisc/feature/expose-process-policy-in…
Browse files Browse the repository at this point in the history
…-ayii-product

Feature/expose process policy in ayii product
  • Loading branch information
matthiaszimmermann committed Sep 19, 2022
2 parents 2ec563a + 8a6badd commit b58fd27
Show file tree
Hide file tree
Showing 15 changed files with 947 additions and 143 deletions.
2 changes: 1 addition & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
"solidity.remappingsUnix": [
"@openzeppelin/=/home/vscode/.brownie/packages/OpenZeppelin/openzeppelin-contracts@4.7.3",
"@chainlink/=/home/vscode/.brownie/packages/smartcontractkit/chainlink@1.6.0",
"@etherisc/gif-interface/=/home/vscode/.brownie/packages/etherisc/gif-interface@3f16cfe",
"@etherisc/gif-interface/=/home/vscode/.brownie/packages/etherisc/gif-interface@3b0002a",
],
"solidity.compileUsingRemoteVersion": "v0.8.2+commit.661d1103",
"peacock.remoteColor": "1D3C43",
Expand Down
4 changes: 2 additions & 2 deletions brownie-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ compiler:
remappings:
- "@openzeppelin=OpenZeppelin/openzeppelin-contracts@4.7.3"
- "@chainlink=smartcontractkit/chainlink@1.6.0"
- "@etherisc/gif-interface=etherisc/gif-interface@3f16cfe"
- "@etherisc/gif-interface=etherisc/gif-interface@3b0002a"

# packages below will be added to brownie
# you may use 'brownie pm list' after 'brownie compile'
Expand All @@ -32,7 +32,7 @@ dependencies:
# github dependency format: <owner>/<repository>@<release>
- OpenZeppelin/openzeppelin-contracts@4.7.3
- smartcontractkit/chainlink@1.6.0
- etherisc/gif-interface@3f16cfe
- etherisc/gif-interface@3b0002a

# exclude open zeppeling contracts when calculating test coverage
# https://eth-brownie.readthedocs.io/en/v1.10.3/config.html#exclude_paths
Expand Down
65 changes: 53 additions & 12 deletions contracts/examples/AyiiProduct.sol
Original file line number Diff line number Diff line change
Expand Up @@ -395,35 +395,76 @@ contract AyiiProduct is

function processPoliciesForRisk(bytes32 riskId, uint256 batchSize)
external
onlyRole(INSURER_ROLE)
returns(bytes32 [] memory processedPolicies)
{
Risk memory risk = _risks[riskId];
require(risk.responseAt > 0, "ERROR:AYI-030:ORACLE_RESPONSE_MISSING");

EnumerableSet.Bytes32Set storage policyIds = _policies[riskId];
uint256 elements = EnumerableSet.length(policyIds);
uint256 elements = EnumerableSet.length(_policies[riskId]);
if (elements == 0) {
emit LogAyiiRiskProcessed(riskId, 0);
return new bytes32[](0);
}

if (batchSize == 0) { batchSize = elements; }
else { batchSize = min(batchSize, elements); }
else { batchSize = min(batchSize, elements); }

processedPolicies = new bytes32[](batchSize);
uint256 elementIdx = elements - 1;

for (uint256 i = 0; i < batchSize; i++) {
// grab and process the last policy
bytes32 policyId = EnumerableSet.at(policyIds, EnumerableSet.length(policyIds) - 1);
_processPolicy(policyId, risk);

_expire(policyId);
_close(policyId);

bytes32 policyId = EnumerableSet.at(_policies[riskId], elementIdx - i);
processPolicy(policyId);
processedPolicies[i] = policyId;

// remove the last (processed) policy from the list
EnumerableSet.remove(policyIds, policyId);
}

emit LogAyiiRiskProcessed(riskId, batchSize);
}

function processPolicy(bytes32 policyId)
public
onlyRole(INSURER_ROLE)
{
IPolicy.Application memory application = _getApplication(policyId);
bytes32 riskId = abi.decode(application.data, (bytes32));
Risk memory risk = _risks[riskId];

require(risk.id == riskId, "ERROR:AYI-031:RISK_ID_INVALID");
require(risk.responseAt > 0, "ERROR:AYI-032:ORACLE_RESPONSE_MISSING");
require(EnumerableSet.contains(_policies[riskId], policyId), "ERROR:AYI-033:POLICY_FOR_RISK_UNKNOWN");

EnumerableSet.remove(_policies[riskId], policyId);


uint256 claimAmount = calculatePayout(
risk.payoutPercentage,
application.sumInsuredAmount);

uint256 claimId = _newClaim(policyId, claimAmount, "");
emit LogAyiiClaimCreated(policyId, claimId, claimAmount);

if (claimAmount > 0) {
uint256 payoutAmount = claimAmount;
_confirmClaim(policyId, claimId, payoutAmount);

uint256 payoutId = _newPayout(policyId, claimId, payoutAmount, "");
_processPayout(policyId, payoutId);

emit LogAyiiPayoutCreated(policyId, payoutAmount);
}
else {
_declineClaim(policyId, claimId);
_closeClaim(policyId, claimId);
}

_expire(policyId);
_close(policyId);

emit LogAyiiPolicyProcessed(policyId);
}

function calculatePayout(uint256 payoutPercentage, uint256 sumInsuredAmount)
public
pure
Expand Down
4 changes: 2 additions & 2 deletions contracts/flows/PolicyDefaultFlow.sol
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ contract PolicyDefaultFlow is
policy.collectPremium(processId, netPremiumAmount + feeAmount);

PoolController pool = getPoolContract();
pool.increaseBalance(processId, netPremiumAmount);
pool.processPremium(processId, netPremiumAmount);
}
}

Expand Down Expand Up @@ -272,7 +272,7 @@ contract PolicyDefaultFlow is
policy.processPayout(processId, payoutId);

PoolController pool = getPoolContract();
pool.decreaseBalance(processId, netPayoutAmount + feeAmount);
pool.processPayout(processId, netPayoutAmount + feeAmount);
}

function request(
Expand Down
118 changes: 75 additions & 43 deletions contracts/modules/BundleController.sol
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,10 @@ contract BundleController is

modifier onlyFundableBundle(uint256 bundleId) {
Bundle storage bundle = _bundles[bundleId];
require(bundle.createdAt > 0, "ERROR:BUC-031:BUNDLE_DOES_NOT_EXIST");
require(bundle.createdAt > 0, "ERROR:BUC-002:BUNDLE_DOES_NOT_EXIST");
require(
bundle.state != IBundle.BundleState.Burned
&& bundle.state != IBundle.BundleState.Closed, "ERROR:BUC-032:BUNDLE_BURNED_OR_CLOSED"
&& bundle.state != IBundle.BundleState.Closed, "ERROR:BUC-003:BUNDLE_BURNED_OR_CLOSED"
);
_;
}
Expand Down Expand Up @@ -182,60 +182,93 @@ contract BundleController is
}


function releasePolicy(uint256 bundleId, bytes32 processId)
external override
function processPremium(uint256 bundleId, bytes32 processId, uint256 amount)
external override
onlyRiskpoolService
returns(uint256 collateralAmount)
onlyFundableBundle(bundleId)
{
// make sure bundle exists and is not yet closed
IPolicy.Policy memory policy = _policy.getPolicy(processId);
require(
policy.state != IPolicy.PolicyState.Closed,
"ERROR:POL-030:POLICY_STATE_INVALID"
);

Bundle storage bundle = _bundles[bundleId];
require(bundle.createdAt > 0, "ERROR:BUC-024:BUNDLE_DOES_NOT_EXIST");
require(_activePolicies[bundleId] > 0, "ERROR:BUC-025:NO_ACTIVE_POLICIES_FOR_BUNDLE");
require(bundle.createdAt > 0, "ERROR:BUC-031:BUNDLE_DOES_NOT_EXIST");

bundle.balance += amount;
bundle.updatedAt = block.timestamp; // solhint-disable-line
}

collateralAmount = _valueLockedPerPolicy[bundleId][processId];
require(collateralAmount > 0, "ERROR:BUC-026:NOT_COLLATERALIZED_BY_BUNDLE");

// this should never ever fail ...
function processPayout(uint256 bundleId, bytes32 processId, uint256 amount)
external override
onlyRiskpoolService
{
IPolicy.Policy memory policy = _policy.getPolicy(processId);
require(
bundle.lockedCapital >= collateralAmount,
"PANIC:BUC-027:UNLOCK_CAPITAL_TOO_BIG"
policy.state != IPolicy.PolicyState.Closed,
"ERROR:POL-040:POLICY_STATE_INVALID"
);

// policy no longer relevant for bundle
_activePolicies[bundleId] -= 1;
delete _valueLockedPerPolicy[bundleId][processId];
// check there are policies and there is sufficient locked capital for policy
require(_activePolicies[bundleId] > 0, "ERROR:BUC-041:NO_ACTIVE_POLICIES_FOR_BUNDLE");
require(_valueLockedPerPolicy[bundleId][processId] >= amount, "ERROR:BUC-042:COLLATERAL_INSUFFICIENT_FOR_POLICY");

// update bundle capital
bundle.lockedCapital -= collateralAmount;
bundle.updatedAt = block.timestamp;
// make sure bundle exists and is not yet closed
Bundle storage bundle = _bundles[bundleId];
require(bundle.createdAt > 0, "ERROR:BUC-043:BUNDLE_DOES_NOT_EXIST");
require(
bundle.state == IBundle.BundleState.Active
|| bundle.state == IBundle.BundleState.Locked,
"ERROR:BUC-044:BUNDLE_STATE_INVALID");
require(bundle.capital >= amount, "ERROR:BUC-045:CAPITAL_TOO_LOW");
require(bundle.lockedCapital >= amount, "ERROR:BUC-046:LOCKED_CAPITAL_TOO_LOW");
require(bundle.balance >= amount, "ERROR:BUC-047:BALANCE_TOO_LOW");

_valueLockedPerPolicy[bundleId][processId] -= amount;
bundle.capital -= amount;
bundle.lockedCapital -= amount;
bundle.balance -= amount;
bundle.updatedAt = block.timestamp; // solhint-disable-line

uint256 capacityAmount = bundle.capital - bundle.lockedCapital;
emit LogBundlePolicyExpired(bundleId, processId, collateralAmount, capacityAmount);
emit LogBundlePayoutProcessed(bundleId, processId, amount);
}


function increaseBalance(uint256 bundleId, uint256 amount)
external override
function releasePolicy(uint256 bundleId, bytes32 processId)
external override
onlyRiskpoolService
onlyFundableBundle(bundleId)
returns(uint256 remainingCollateralAmount)
{
IPolicy.Policy memory policy = _policy.getPolicy(processId);
require(
policy.state == IPolicy.PolicyState.Closed,
"ERROR:POL-050:POLICY_STATE_INVALID"
);

// make sure bundle exists and is not yet closed
Bundle storage bundle = _bundles[bundleId];
bundle.balance += amount;
bundle.updatedAt = block.timestamp;
}
require(bundle.createdAt > 0, "ERROR:BUC-051:BUNDLE_DOES_NOT_EXIST");
require(_activePolicies[bundleId] > 0, "ERROR:BUC-052:NO_ACTIVE_POLICIES_FOR_BUNDLE");

uint256 lockedForPolicyAmount = _valueLockedPerPolicy[bundleId][processId];
// this should never ever fail ...
require(
bundle.lockedCapital >= lockedForPolicyAmount,
"PANIC:BUC-053:UNLOCK_CAPITAL_TOO_BIG"
);

function decreaseBalance(uint256 bundleId, uint256 amount)
external override
onlyRiskpoolService
onlyFundableBundle(bundleId)
{
Bundle storage bundle = _bundles[bundleId];
// policy no longer relevant for bundle
_activePolicies[bundleId] -= 1;
delete _valueLockedPerPolicy[bundleId][processId];

require(bundle.balance >= amount, "ERROR:BUC-035:BUNDLE_BALANCE_TOO_SMALL");
// update bundle capital
bundle.lockedCapital -= lockedForPolicyAmount;
bundle.updatedAt = block.timestamp; // solhint-disable-line

bundle.balance -= amount;
bundle.updatedAt = block.timestamp;
uint256 capacityAmount = bundle.capital - bundle.lockedCapital;
emit LogBundlePolicyReleased(bundleId, processId, lockedForPolicyAmount, capacityAmount);
}

function getOwner(uint256 bundleId) public view returns(address) {
Expand Down Expand Up @@ -270,7 +303,7 @@ contract BundleController is

function getBundle(uint256 bundleId) public view returns(Bundle memory) {
Bundle memory bundle = _bundles[bundleId];
require(bundle.createdAt > 0, "ERROR:BUC-040:BUNDLE_DOES_NOT_EXIST");
require(bundle.createdAt > 0, "ERROR:BUC-060:BUNDLE_DOES_NOT_EXIST");
return bundle;
}

Expand Down Expand Up @@ -308,23 +341,22 @@ contract BundleController is
if (oldState == BundleState.Active) {
require(
newState == BundleState.Locked || newState == BundleState.Closed,
"ERROR:BUC-050:ACTIVE_INVALID_TRANSITION"
"ERROR:BUC-070:ACTIVE_INVALID_TRANSITION"
);
} else if (oldState == BundleState.Locked) {
require(
newState == BundleState.Active || newState == BundleState.Closed,
"ERROR:BUC-051:LOCKED_INVALID_TRANSITION"
"ERROR:BUC-071:LOCKED_INVALID_TRANSITION"
);
} else if (oldState == BundleState.Closed) {
require(
newState == BundleState.Burned,
"ERROR:BUC-052:CLOSED_INVALID_TRANSITION"
"ERROR:BUC-072:CLOSED_INVALID_TRANSITION"
);
} else if (oldState == BundleState.Burned) {
revert("ERROR:BUC-053:BURNED_IS_FINAL_STATE");
revert("ERROR:BUC-073:BURNED_IS_FINAL_STATE");
} else {
revert("ERROR:BOC-054:INITIAL_STATE_NOT_HANDLED");
revert("ERROR:BOC-074:INITIAL_STATE_NOT_HANDLED");
}
}

}
Loading

0 comments on commit b58fd27

Please sign in to comment.