Skip to content

Commit

Permalink
move ClaimInfo storage to ProductStore (#660)
Browse files Browse the repository at this point in the history
  • Loading branch information
doerfli committed Sep 17, 2024
1 parent 27fee6d commit d7d2ee2
Show file tree
Hide file tree
Showing 9 changed files with 67 additions and 50 deletions.
4 changes: 2 additions & 2 deletions contracts/instance/InstanceAuthorizationV3.sol
Original file line number Diff line number Diff line change
Expand Up @@ -229,8 +229,6 @@ contract InstanceAuthorizationV3

// authorize claim service role
functions = _authorizeForTarget(INSTANCE_STORE_TARGET_NAME, getServiceRole(CLAIM()));
_authorize(functions, InstanceStore.createClaim.selector, "createClaim");
_authorize(functions, InstanceStore.updateClaim.selector, "updateClaim");
_authorize(functions, InstanceStore.createPayout.selector, "createPayout");
_authorize(functions, InstanceStore.updatePayout.selector, "updatePayout");
_authorize(functions, InstanceStore.updatePayoutState.selector, "updatePayoutState");
Expand Down Expand Up @@ -272,6 +270,8 @@ contract InstanceAuthorizationV3
// authorize claim service role
functions = _authorizeForTarget(PRODUCT_STORE_TARGET_NAME, getServiceRole(CLAIM()));
_authorize(functions, ProductStore.updatePolicyClaims.selector, "updatePolicyClaims");
_authorize(functions, ProductStore.createClaim.selector, "createClaim");
_authorize(functions, ProductStore.updateClaim.selector, "updateClaim");
}
}

9 changes: 3 additions & 6 deletions contracts/instance/InstanceReader.sol
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import {IRisk} from "../instance/module/IRisk.sol";
import {AccessAdminLib} from "../authorization/AccessAdminLib.sol";
import {Amount} from "../type/Amount.sol";
import {BundleSet} from "./BundleSet.sol";
import {BUNDLE, COMPONENT, DISTRIBUTOR, DISTRIBUTION, FEE, PREMIUM, POLICY, POOL, PRODUCT} from "../type/ObjectType.sol";
import {BUNDLE, COMPONENT, DISTRIBUTOR, DISTRIBUTION, PREMIUM, POLICY, POOL} from "../type/ObjectType.sol";
import {ClaimId, ClaimIdLib} from "../type/ClaimId.sol";
import {DistributorType} from "../type/DistributorType.sol";
import {InstanceAdmin} from "./InstanceAdmin.sol";
Expand Down Expand Up @@ -281,16 +281,13 @@ contract InstanceReader {

/// @dev Returns the claim info for the given policy NFT ID and claim ID.
function getClaimInfo(NftId policyNftId, ClaimId claimId) public view returns (IPolicy.ClaimInfo memory info) {
(bytes memory data, bool success) = _getData(claimId.toKey32(policyNftId));
if (success) {
return abi.decode(data, (IPolicy.ClaimInfo));
}
return _productStore.getClaimInfo(policyNftId, claimId);
}


/// @dev Returns the current claim state for the given policy NFT ID and claim ID.
function getClaimState(NftId policyNftId, ClaimId claimId) public view returns (StateId state) {
return getState(claimId.toKey32(policyNftId));
return _productStore.getState(claimId.toKey32(policyNftId));
}


Expand Down
13 changes: 0 additions & 13 deletions contracts/instance/InstanceStore.sol
Original file line number Diff line number Diff line change
Expand Up @@ -143,19 +143,6 @@ contract InstanceStore is
_updateState(_toNftKey32(bundleNftId, BUNDLE()), newState);
}

//--- Claim -------------------------------------------------------------//
function createClaim(NftId policyNftId, ClaimId claimId, IPolicy.ClaimInfo memory claim) external restricted() {
_create(_toClaimKey32(policyNftId, claimId), abi.encode(claim));
}

function updateClaim(NftId policyNftId, ClaimId claimId, IPolicy.ClaimInfo memory claim, StateId newState) external restricted() {
_update(_toClaimKey32(policyNftId, claimId), abi.encode(claim), newState);
}

function updateClaimState(NftId policyNftId, ClaimId claimId, StateId newState) external restricted() {
_updateState(_toClaimKey32(policyNftId, claimId), newState);
}

//--- Payout ------------------------------------------------------------//
function createPayout(NftId policyNftId, PayoutId payoutId, IPolicy.PayoutInfo memory payout) external restricted() {
_create(_toPayoutKey32(policyNftId, payoutId), abi.encode(payout));
Expand Down
36 changes: 36 additions & 0 deletions contracts/instance/ProductStore.sol
Original file line number Diff line number Diff line change
Expand Up @@ -39,12 +39,15 @@ contract ProductStore is
event LogProductStorePolicyInfoUpdated(NftId policyNftId, StateId oldState, StateId newState, address updatedBy, address txOrigin, Blocknumber lastUpdatedIn);
event LogProductStorePremiumInfoCreated(NftId policyNftId, StateId state, address createdBy, address txOrigin);
event LogProductStorePremiumInfoUpdated(NftId policyNftId, StateId oldState, StateId newState, address updatedBy, address txOrigin, Blocknumber lastUpdatedIn);
event LogProductStoreClaimInfoCreated(NftId policyNftId, ClaimId claimId, StateId state, address createdBy, address txOrigin);
event LogProductStoreClaimInfoUpdated(NftId policyNftId, ClaimId claimId, StateId oldState, StateId newState, address updatedBy, address txOrigin, Blocknumber lastUpdatedIn);

mapping(Key32 key32 => IComponents.ProductInfo) private _products;
mapping(Key32 key32 => IComponents.FeeInfo) private _fees;
mapping(Key32 key32 => IRisk.RiskInfo) private _risks;
mapping(Key32 key32 => IPolicy.PolicyInfo) private _policies;
mapping(Key32 key32 => IPolicy.PremiumInfo) private _premiums;
mapping(Key32 key32 => IPolicy.ClaimInfo) private _claims;


/// @dev This initializer needs to be called from the instance itself.
Expand Down Expand Up @@ -220,6 +223,39 @@ contract ProductStore is
return _premiums[_toNftKey32(policyNftId, PREMIUM())];
}

//--- Claim -------------------------------------------------------------//

function createClaim(NftId policyNftId, ClaimId claimId, IPolicy.ClaimInfo memory claim) external restricted() {
// _create(_toClaimKey32(policyNftId, claimId), abi.encode(claim));

Key32 key = _toClaimKey32(policyNftId, claimId);
_createMetadata(key);
_claims[key] = claim;
// solhint-disable-next-line avoid-tx-origin
emit LogProductStoreClaimInfoCreated(policyNftId, claimId, getState(key), msg.sender, tx.origin);
}

function updateClaim(NftId policyNftId, ClaimId claimId, IPolicy.ClaimInfo memory claim, StateId newState) external restricted() {
Key32 key = _toClaimKey32(policyNftId, claimId);
Blocknumber lastUpdatedIn = _updateState(key, newState);
StateId oldState = getState(key);
_claims[key] = claim;
// solhint-disable-next-line avoid-tx-origin
emit LogProductStoreClaimInfoUpdated(policyNftId, claimId, oldState, newState, msg.sender, tx.origin, lastUpdatedIn);
}

function updateClaimState(NftId policyNftId, ClaimId claimId, StateId newState) external restricted() {
Key32 key = _toClaimKey32(policyNftId, claimId);
Blocknumber lastUpdatedIn = _updateState(key, newState);
StateId oldState = getState(key);
// solhint-disable-next-line avoid-tx-origin
emit LogProductStoreClaimInfoUpdated(policyNftId, claimId, oldState, newState, msg.sender, tx.origin, lastUpdatedIn);
}

function getClaimInfo(NftId policyNftId, ClaimId claimId) external view returns (IPolicy.ClaimInfo memory claim) {
return _claims[_toClaimKey32(policyNftId, claimId)];
}

//--- internal view/pure functions --------------------------------------//
function _toNftKey32(NftId nftId, ObjectType objectType) private pure returns (Key32) {
return nftId.toKey32(objectType);
Expand Down
18 changes: 9 additions & 9 deletions contracts/product/ClaimService.sol
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ contract ClaimService is
// effects
// create new claim
claimId = ClaimIdLib.toClaimId(policyInfo.claimsCount + 1);
instanceContracts.instanceStore.createClaim(
instanceContracts.productStore.createClaim(
policyNftId,
claimId,
IPolicy.ClaimInfo({
Expand Down Expand Up @@ -132,7 +132,7 @@ contract ClaimService is
IPolicy.ClaimInfo memory claimInfo = _verifyClaim(instanceContracts.instanceReader, policyNftId, claimId, SUBMITTED());
claimInfo.claimAmount = confirmedAmount;
claimInfo.processData = data;
instanceContracts.instanceStore.updateClaim(policyNftId, claimId, claimInfo, CONFIRMED());
instanceContracts.productStore.updateClaim(policyNftId, claimId, claimInfo, CONFIRMED());

// update and save policy info with instance
policyInfo.claimAmount = policyInfo.claimAmount + confirmedAmount;
Expand Down Expand Up @@ -176,7 +176,7 @@ contract ClaimService is
IPolicy.ClaimInfo memory claimInfo = _verifyClaim(instanceContracts.instanceReader, policyNftId, claimId, SUBMITTED());
claimInfo.processData = data;
claimInfo.closedAt = TimestampLib.current();
instanceContracts.instanceStore.updateClaim(policyNftId, claimId, claimInfo, DECLINED());
instanceContracts.productStore.updateClaim(policyNftId, claimId, claimInfo, DECLINED());

// update and save policy info with instance
policyInfo.openClaimsCount -= 1;
Expand Down Expand Up @@ -204,7 +204,7 @@ contract ClaimService is
// check/update claim info
IPolicy.ClaimInfo memory claimInfo = _verifyClaim(instanceContracts.instanceReader, policyNftId, claimId, SUBMITTED());
claimInfo.closedAt = TimestampLib.current();
instanceContracts.instanceStore.updateClaim(policyNftId, claimId, claimInfo, REVOKED());
instanceContracts.productStore.updateClaim(policyNftId, claimId, claimInfo, REVOKED());

// update and save policy info with instance
policyInfo.openClaimsCount -= 1;
Expand Down Expand Up @@ -242,7 +242,7 @@ contract ClaimService is
}

claimInfo.closedAt = TimestampLib.current();
instanceContracts.instanceStore.updateClaim(policyNftId, claimId, claimInfo, CANCELLED());
instanceContracts.productStore.updateClaim(policyNftId, claimId, claimInfo, CANCELLED());

emit LogClaimServiceClaimCancelled(policyNftId, claimId);
}
Expand Down Expand Up @@ -354,11 +354,11 @@ contract ClaimService is
// update claim and policy info accordingly
if(claimInfo.openPayoutsCount == 0 && claimInfo.paidAmount == claimInfo.claimAmount) {
claimInfo.closedAt = TimestampLib.current();
instanceContracts.instanceStore.updateClaim(policyNftId, claimId, claimInfo, CLOSED());
instanceContracts.productStore.updateClaim(policyNftId, claimId, claimInfo, CLOSED());

policyInfo.openClaimsCount -= 1;
} else {
instanceContracts.instanceStore.updateClaim(policyNftId, claimId, claimInfo, KEEP_STATE());
instanceContracts.productStore.updateClaim(policyNftId, claimId, claimInfo, KEEP_STATE());
}
}

Expand Down Expand Up @@ -408,7 +408,7 @@ contract ClaimService is
ClaimId claimId = payoutId.toClaimId();
IPolicy.ClaimInfo memory claimInfo = instanceContracts.instanceReader.getClaimInfo(policyNftId, claimId);
claimInfo.openPayoutsCount -= 1;
instanceContracts.instanceStore.updateClaim(policyNftId, claimId, claimInfo, KEEP_STATE());
instanceContracts.productStore.updateClaim(policyNftId, claimId, claimInfo, KEEP_STATE());
}

emit LogClaimServicePayoutCancelled(policyNftId, payoutId);
Expand Down Expand Up @@ -494,7 +494,7 @@ contract ClaimService is
// update and save claim info with instance
claimInfo.payoutsCount += 1;
claimInfo.openPayoutsCount += 1;
instanceContracts.instanceStore.updateClaim(policyNftId, claimId, claimInfo, KEEP_STATE());
instanceContracts.productStore.updateClaim(policyNftId, claimId, claimInfo, KEEP_STATE());

emit LogClaimServicePayoutCreated(policyNftId, payoutId, amount, beneficiary);
}
Expand Down
1 change: 0 additions & 1 deletion contracts/product/RiskService.sol
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import {ObjectType, COMPONENT, PRODUCT, RISK} from "../type/ObjectType.sol";
import {ACTIVE, KEEP_STATE, CLOSED} from "../type/StateId.sol";
import {NftId} from "../type/NftId.sol";
import {RiskId, RiskIdLib} from "../type/RiskId.sol";
import {StateId} from "../type/StateId.sol";
import {RiskSet} from "../instance/RiskSet.sol";
import {Service} from "../shared/Service.sol";
import {TimestampLib} from "../type/Timestamp.sol";
Expand Down
6 changes: 2 additions & 4 deletions contracts/shared/ComponentService.sol
Original file line number Diff line number Diff line change
Expand Up @@ -321,7 +321,6 @@ contract ComponentService is

/// @dev registers the sending component as a distribution component
function _createDistribution(
InstanceStore instanceStore,
ProductStore productStore,
NftId productNftId,
NftId distributionNftId,
Expand Down Expand Up @@ -381,7 +380,6 @@ contract ComponentService is
//-------- oracle -------------------------------------------------------//

function _createOracle(
InstanceStore instanceStore,
ProductStore productStore,
NftId productNftId,
NftId oracleNftId,
Expand Down Expand Up @@ -523,9 +521,9 @@ contract ComponentService is
if(componentType == POOL()) {
_createPool(instanceStore, instance.getProductStore(), productNftId, componentNftId, componentAddress, productInfo);
} else if(componentType == DISTRIBUTION()) {
_createDistribution(instanceStore, instance.getProductStore(), productNftId, componentNftId, productInfo);
_createDistribution(instance.getProductStore(), productNftId, componentNftId, productInfo);
} else if(componentType == ORACLE()) {
_createOracle(instanceStore, instance.getProductStore(), productNftId, componentNftId, productInfo);
_createOracle(instance.getProductStore(), productNftId, componentNftId, productInfo);
} else {
revert ErrorComponentServiceComponentTypeNotSupported(componentAddress, componentType);
}
Expand Down
2 changes: 1 addition & 1 deletion foundry.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ cache_path = 'cache_forge'
gas_limit = "18446744073709551615" # u64::MAX
ffi = true

gas_reports = ["ApplicationService", "PolicyService", "PricingService"]
gas_reports = ["ApplicationService", "PolicyService", "PricingService", "InstanceStore", "ProductStore", "RegistryService"]


[profile.ci]
Expand Down
28 changes: 14 additions & 14 deletions test/component/product/ProductClaim.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import {NftId} from "../../../contracts/type/NftId.sol";
import {ClaimId} from "../../../contracts/type/ClaimId.sol";
import {IPolicy} from "../../../contracts/instance/module/IPolicy.sol";
import {Seconds, SecondsLib} from "../../../contracts/type/Seconds.sol";
import {Timestamp, TimestampLib, zeroTimestamp} from "../../../contracts/type/Timestamp.sol";
import {Timestamp, TimestampLib} from "../../../contracts/type/Timestamp.sol";
import {PayoutId} from "../../../contracts/type/PayoutId.sol";
import {RiskId} from "../../../contracts/type/RiskId.sol";
import {ReferralLib} from "../../../contracts/type/Referral.sol";
Expand Down Expand Up @@ -206,10 +206,10 @@ contract TestProductClaim is GifTest {

// THEN
// checking last of 4 logs
assertEq(entries.length, 4, "unexpected number of logs");
assertEq(entries[3].emitter, address(claimService), "unexpected emitter");
assertEq(entries[3].topics[0], keccak256("LogClaimServiceClaimConfirmed(uint96,uint16,uint96)"), "unexpected log signature");
(uint96 nftIdInt,uint24 claimIdInt, uint96 amountInt ) = abi.decode(entries[3].data, (uint96,uint16,uint96));
assertEq(entries.length, 3, "unexpected number of logs");
assertEq(entries[2].emitter, address(claimService), "unexpected emitter");
assertEq(entries[2].topics[0], keccak256("LogClaimServiceClaimConfirmed(uint96,uint16,uint96)"), "unexpected log signature");
(uint96 nftIdInt,uint24 claimIdInt, uint96 amountInt ) = abi.decode(entries[2].data, (uint96,uint16,uint96));
assertEq(nftIdInt, policyNftId.toInt(), "unexpected policy nft id");
assertEq(claimIdInt, claimId.toInt(), "unexpected claim id");
assertEq(amountInt, confirmedAmount.toInt(), "unexpected amount");
Expand Down Expand Up @@ -245,16 +245,16 @@ contract TestProductClaim is GifTest {
// WHEN
// emit LogPolicyServiceClaimDeclined(policyNftId, ClaimId.wrap(1));
vm.recordLogs();
string memory processData = "claim invalid";
// string memory processData = "claim invalid";
product.revokeClaim(policyNftId, claimId);
Vm.Log[] memory entries = vm.getRecordedLogs();

// THEN
// checking last of 4 logs
assertEq(entries.length, 4, "unexpected number of logs");
assertEq(entries[3].emitter, address(claimService), "unexpected emitter");
assertEq(entries[3].topics[0], keccak256("LogClaimServiceClaimRevoked(uint96,uint16)"), "unexpected log signature");
(uint96 nftIdInt ,uint24 claimIdInt) = abi.decode(entries[3].data, (uint96,uint16));
assertEq(entries.length, 3, "unexpected number of logs");
assertEq(entries[2].emitter, address(claimService), "unexpected emitter");
assertEq(entries[2].topics[0], keccak256("LogClaimServiceClaimRevoked(uint96,uint16)"), "unexpected log signature");
(uint96 nftIdInt ,uint24 claimIdInt) = abi.decode(entries[2].data, (uint96,uint16));
assertEq(nftIdInt, policyNftId.toInt(), "unexpected policy nft id");
assertEq(claimIdInt, claimId.toInt(), "unexpected claim id");

Expand Down Expand Up @@ -297,10 +297,10 @@ contract TestProductClaim is GifTest {

// THEN
// checking last of 4 logs
assertEq(entries.length, 4, "unexpected number of logs");
assertEq(entries[3].emitter, address(claimService), "unexpected emitter");
assertEq(entries[3].topics[0], keccak256("LogClaimServiceClaimDeclined(uint96,uint16)"), "unexpected log signature");
(uint96 nftIdInt ,uint24 claimIdInt) = abi.decode(entries[3].data, (uint96,uint16));
assertEq(entries.length, 3, "unexpected number of logs");
assertEq(entries[2].emitter, address(claimService), "unexpected emitter");
assertEq(entries[2].topics[0], keccak256("LogClaimServiceClaimDeclined(uint96,uint16)"), "unexpected log signature");
(uint96 nftIdInt ,uint24 claimIdInt) = abi.decode(entries[2].data, (uint96,uint16));
assertEq(nftIdInt, policyNftId.toInt(), "unexpected policy nft id");
assertEq(claimIdInt, claimId.toInt(), "unexpected claim id");

Expand Down

0 comments on commit d7d2ee2

Please sign in to comment.