Skip to content

Commit

Permalink
add close to PolicyService (#178)
Browse files Browse the repository at this point in the history
  • Loading branch information
doerfli committed Feb 16, 2024
1 parent 5c041ae commit ac24b4a
Show file tree
Hide file tree
Showing 6 changed files with 102 additions and 4 deletions.
8 changes: 8 additions & 0 deletions contracts/components/Product.sol
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,14 @@ abstract contract Product is BaseComponent, IProductComponent {
activateAt);
}

function _close(
NftId policyNftId
)
internal
{
_policyService.close(policyNftId);
}

function getPoolNftId() external view override returns (NftId poolNftId) {
return getRegistry().getNftId(address(_pool));
}
Expand Down
23 changes: 21 additions & 2 deletions contracts/instance/service/BundleService.sol
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,25 @@ contract BundleService is
instance.updateBundle(bundleNftId, bundleInfo, KEEP_STATE());
}

function closePolicy(IInstance instance,
NftId policyNftId,
NftId bundleNftId,
uint256 collateralAmount
)
external
onlyService
{
InstanceReader instanceReader = instance.getInstanceReader();
IBundle.BundleInfo memory bundleInfo = instanceReader.getBundleInfo(bundleNftId);

// lock collateral
bundleInfo.lockedAmount -= collateralAmount;

instance.updateBundle(bundleNftId, bundleInfo, KEEP_STATE());

unlinkPolicy(instance, policyNftId);
}

/// @dev links policy to bundle
function linkPolicy(IInstance instance, NftId policyNftId)
internal
Expand Down Expand Up @@ -234,8 +253,8 @@ contract BundleService is
}

// ensure policy is closeable
if (policyInfo.expiredAt < TimestampLib.blockTimestamp()
|| policyInfo.payoutAmount < policyInfo.sumInsuredAmount)
if ( TimestampLib.blockTimestamp() < policyInfo.expiredAt
&& policyInfo.payoutAmount < policyInfo.sumInsuredAmount)
{
revert BundleManager.ErrorBundleManagerPolicyNotCloseable(policyNftId);
}
Expand Down
2 changes: 2 additions & 0 deletions contracts/instance/service/IBundleService.sol
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ interface IBundleService is IService {

function increaseBalance(IInstance instance, NftId bundleNftId, uint256 amount) external;

function closePolicy(IInstance instance, NftId policyNftId, NftId bundleNftId, uint256 collateralAmount) external;

// function fundBundle(NftId bundleNftId, uint256 amount) external returns(uint256 netAmount);

// function defundBundle(NftId bundleNftId, uint256 amount) external returns(uint256 netAmount);
Expand Down
4 changes: 3 additions & 1 deletion contracts/instance/service/PolicyService.sol
Original file line number Diff line number Diff line change
Expand Up @@ -473,11 +473,13 @@ contract PolicyService is ComponentServiceBase, IPolicyService {
revert ErrorIPolicyServiceOpenClaims(policyNftId, policyInfo.openClaimsCount);
}

if (policyInfo.expiredAt.lt(TimestampLib.blockTimestamp()) && policyInfo.payoutAmount < policyInfo.sumInsuredAmount) {
if (TimestampLib.blockTimestamp().lte(policyInfo.expiredAt) && (policyInfo.payoutAmount < policyInfo.sumInsuredAmount)) {
revert ErrorIPolicyServicePolicyHasNotExpired(policyNftId, policyInfo.expiredAt);
}

policyInfo.closedAt = TimestampLib.blockTimestamp();

_bundleService.closePolicy(instance, policyNftId, policyInfo.bundleNftId, policyInfo.sumInsuredAmount);
instance.updatePolicy(policyNftId, policyInfo, CLOSED());
}

Expand Down
63 changes: 62 additions & 1 deletion test_forge/TestProduct.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import {Timestamp, TimestampLib, zeroTimestamp} from "../contracts/types/Timesta
import {IRisk} from "../contracts/instance/module/IRisk.sol";
import {RiskId, RiskIdLib, eqRiskId} from "../contracts/types/RiskId.sol";
import {ReferralLib} from "../contracts/types/Referral.sol";
import {APPLIED, ACTIVE, UNDERWRITTEN} from "../contracts/types/StateId.sol";
import {APPLIED, ACTIVE, UNDERWRITTEN, CLOSED} from "../contracts/types/StateId.sol";
import {POLICY} from "../contracts/types/ObjectType.sol";

contract TestProduct is TestGifBase {
Expand Down Expand Up @@ -395,6 +395,67 @@ contract TestProduct is TestGifBase {
assertEq(token.balanceOf(address(pool)), 10130, "pool balance not 130");
}

function test_Product_close() public {
// GIVEN
vm.startPrank(registryOwner);
token.transfer(customer, 1000);
vm.stopPrank();

_prepareProduct();

vm.startPrank(productOwner);

Fee memory productFee = FeeLib.toFee(UFixedLib.zero(), 10);
product.setFees(productFee, FeeLib.zeroFee());

RiskId riskId = RiskIdLib.toRiskId("42x4711");
bytes memory data = "bla di blubb";
SimpleProduct dproduct = SimpleProduct(address(product));
dproduct.createRisk(riskId, data);

vm.stopPrank();

vm.startPrank(customer);

ISetup.ProductSetupInfo memory productSetupInfo = instanceReader.getProductSetupInfo(productNftId);
token.approve(address(productSetupInfo.tokenHandler), 1000);
// revert("checkApprove");

NftId policyNftId = dproduct.createApplication(
customer,
riskId,
1000,
30,
"",
bundleNftId,
ReferralLib.zero()
);
vm.stopPrank();

vm.startPrank(productOwner);
dproduct.underwrite(policyNftId, true, TimestampLib.blockTimestamp());

assertTrue(instanceReader.getPolicyState(policyNftId) == ACTIVE(), "policy state not UNDERWRITTEN");

// WHEN
vm.warp(100); // warp 100 seconds
dproduct.close(policyNftId);

// THEN
assertTrue(instanceReader.getPolicyState(policyNftId) == CLOSED(), "policy state not CLOSE");

IBundle.BundleInfo memory bundleInfo = instanceReader.getBundleInfo(bundleNftId);
assertEq(bundleInfo.lockedAmount, 0, "lockedAmount not 1000");
assertEq(bundleInfo.balanceAmount, 10000 + 130, "balanceAmount not 10130");

IPolicy.PolicyInfo memory policyInfo = instanceReader.getPolicyInfo(policyNftId);
assertTrue(policyInfo.closedAt.gtz(), "expiredAt not set");

assertEq(token.balanceOf(address(pool)), 10130, "pool balance not 130");

assertEq(instanceBundleManager.activePolicies(bundleNftId), 0, "expected no active policy");
}

function test_createRisk() public {
_prepareProduct();
vm.startPrank(productOwner);
Expand Down
6 changes: 6 additions & 0 deletions test_forge/mock/SimpleProduct.sol
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,12 @@ contract SimpleProduct is Product {
_activate(policyNftId, activateAt);
}

function close(
NftId policyNftId
) public {
_close(policyNftId);
}

function doSomethingSpecial()
public
onlyInstanceRole(SPECIAL_ROLE_INT)
Expand Down

0 comments on commit ac24b4a

Please sign in to comment.