Skip to content

Commit

Permalink
Check riskpool balance and allowance before payout
Browse files Browse the repository at this point in the history
  • Loading branch information
doerfli committed Sep 16, 2022
1 parent 67c497b commit bdaaa6f
Show file tree
Hide file tree
Showing 3 changed files with 81 additions and 84 deletions.
9 changes: 7 additions & 2 deletions contracts/modules/TreasuryModule.sol
Original file line number Diff line number Diff line change
Expand Up @@ -335,14 +335,19 @@ contract TreasuryModule is
token.balanceOf(riskpoolWalletAddress) >= payout.amount,
"ERROR:TRS-042:RISKPOOL_BALANCE_TOO_SMALL"
);
require(
token.allowance(riskpoolWalletAddress, address(this)) >= payout.amount,
"ERROR:TRS-043:PAYOUT_ALLOWANCE_TOO_SMALL"
);


// actual payout to policy holder
bool success = TransferHelper.unifiedTransferFrom(token, riskpoolWalletAddress, metadata.owner, payout.amount);
feeAmount = 0;
netPayoutAmount = payout.amount;

emit LogTreasuryPayoutTransferred(riskpoolWalletAddress, metadata.owner, payout.amount);
require(success, "ERROR:TRS-043:PAYOUT_TRANSFER_FAILED");
require(success, "ERROR:TRS-044:PAYOUT_TRANSFER_FAILED");

emit LogTreasuryPayoutProcessed(riskpoolId, metadata.owner, payout.amount);
}
Expand Down Expand Up @@ -374,7 +379,7 @@ contract TreasuryModule is

// check balance and allowance before starting any transfers
require(token.balanceOf(bundleOwner) >= capitalAmount, "ERROR:TRS-052:BALANCE_TOO_SMALL");
require(token.allowance(bundleOwner, address(this)) >= capitalAmount, "ERROR:TRS-053:ALLOWANCE_TOO_SMALL");
require(token.allowance(bundleOwner, address(this)) >= capitalAmount, "ERROR:TRS-053:CAPITAL_TRANSFER_ALLOWANCE_TOO_SMALL");

bool success = TransferHelper.unifiedTransferFrom(token, bundleOwner, _instanceWalletAddress, feeAmount);

Expand Down
79 changes: 0 additions & 79 deletions tests/test_treasury_module.py
Original file line number Diff line number Diff line change
Expand Up @@ -162,85 +162,6 @@ def test_bundle_withdrawal_allowance_too_small(
{'from': riskpoolKeeper})


def test_payout_allowance_too_small(
instance: GifInstance,
owner: Account,
testCoin,
productOwner: Account,
oracleProvider: Account,
riskpoolKeeper: Account,
capitalOwner: Account,
customer: Account,
):
applicationFilter = bytes(0)

(gifProduct, gifRiskpool, gifOracle) = getProductAndRiskpool(
instance,
owner,
testCoin,
productOwner,
oracleProvider,
riskpoolKeeper,
capitalOwner,
True
)

# prepare product and riskpool
safetyFactor = 2
amount = 10000
testCoin.transfer(riskpoolKeeper, safetyFactor * amount, {'from': owner})
testCoin.approve(instance.getTreasury(), amount, {'from': riskpoolKeeper})
riskpool = gifRiskpool.getContract()

# fund bundle
riskpool.createBundle(
applicationFilter,
amount,
{'from': riskpoolKeeper})

bundle = riskpool.getBundle(0)
print(bundle)

(bundleId) = bundle[0]

# check bundle values with expectation
assert bundleId == 1

# prepare prolicy application
premium = 100
sumInsured = 1000
product = gifProduct.getContract()
policyController = instance.getPolicy()

policyId = apply_for_policy(instance, owner, product, customer, testCoin, premium, sumInsured)

claimAmount = 800
instanceService = instance.getInstanceService()

# submit a claim for the policy
tx = product.submitClaimWithDeferredResponse(policyId, claimAmount, {'from': customer})
(claimId, requestId) = tx.return_value
claim = instanceService.getClaim(policyId, claimId).dict()
print(claim)

assert claim["state"] == 0 # enum ClaimState {Applied, Confirmed, Declined, Closed}

# confirm the claim
product.confirmClaim(policyId, claimId, claimAmount, {'from': productOwner})

claim = instanceService.getClaim(policyId, claimId).dict()
assert claim["state"] == 1 # enum ClaimState {Applied, Confirmed, Declined, Closed}

# check that it's possible to create payout for claim in confirmed state
payoutAmount = claimAmount

# prepare allowance for payout that is too small
testCoin.approve(instance.getTreasury(), payoutAmount * 0.9, {'from': capitalOwner})

# ensure that the payout fails due to too small allowance
with brownie.reverts("ERROR:TRS-043:PAYOUT_TRANSFER_FAILED"):
product.createPayout(policyId, claimId, payoutAmount, {'from': productOwner})

def test_two_products_different_coin_same_riskpool(
instance: GifInstance,
owner: Account,
Expand Down
77 changes: 74 additions & 3 deletions tests/test_treasury_module_guards.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
from time import process_time
import brownie
import pytest

Expand Down Expand Up @@ -160,7 +161,77 @@ def test_guard_processPayout(

with brownie.reverts("ERROR:CRC-003:NOT_PRODUCT_SERVICE"):
instance.getTreasury().processPayout(processId, "123", {'from': theOutsider})



def test_processPayout_balance_allowance_checks(
instance: GifInstance,
owner: Account,
testCoin,
productOwner: Account,
oracleProvider: Account,
riskpoolKeeper: Account,
capitalOwner: Account,
customer: Account,
riskpoolWallet: Account,
):
applicationFilter = bytes(0)

# prepare product and riskpool
(gifProduct, gifRiskpool, gifOracle) = getProductAndRiskpool(
instance,
owner,
testCoin,
productOwner,
oracleProvider,
riskpoolKeeper,
capitalOwner,
True
)
instanceService = instance.getInstanceService()

# fund bundle
safetyFactor = 2
amount = 10000
testCoin.transfer(riskpoolKeeper, safetyFactor * amount, {'from': owner})
testCoin.approve(instance.getTreasury(), amount, {'from': riskpoolKeeper})
riskpool = gifRiskpool.getContract()

riskpool.createBundle(
applicationFilter,
amount,
{'from': riskpoolKeeper})

bundle = riskpool.getBundle(0)
print(bundle)

# prepare prolicy application
premium = 100
sumInsured = 1000
product = gifProduct.getContract()
policyController = instance.getPolicy()

# apply for policy, then submit and confirm claim
processId = apply_for_policy(instance, owner, product, customer, testCoin, premium, sumInsured)
tx = product.submitClaimNoOracle(processId, sumInsured, {'from': customer})
claimId = tx.return_value
product.confirmClaim(processId, claimId, sumInsured, {'from': productOwner})

# empty riskpool to test balance checks
riskpoolWalletBalance = testCoin.balanceOf(riskpoolWallet)
testCoin.transfer(productOwner, riskpoolWalletBalance, {'from': riskpoolWallet})

with brownie.reverts("ERROR:TRS-042:RISKPOOL_BALANCE_TOO_SMALL"):
product.createPayout(processId, claimId, sumInsured, {'from': productOwner})

# refill riskpool
testCoin.transfer(riskpoolWallet, riskpoolWalletBalance, {'from': productOwner})

with brownie.reverts("ERROR:TRS-043:PAYOUT_ALLOWANCE_TOO_SMALL"):
product.createPayout(processId, claimId, sumInsured, {'from': productOwner})

testCoin.approve(instance.getTreasury(), sumInsured, {'from': riskpoolWallet})
product.createPayout(processId, claimId, sumInsured, {'from': productOwner})


def test_guard_processCapital(
instance: GifInstance,
Expand Down Expand Up @@ -315,15 +386,15 @@ def test_processCapital_balance_allowance_checks(

# ensure bundle cannot be created without allowance
testCoin.transfer(riskpoolKeeper, 0.5 * amount, {'from': owner})
with brownie.reverts("ERROR:TRS-053:ALLOWANCE_TOO_SMALL"):
with brownie.reverts("ERROR:TRS-053:CAPITAL_TRANSFER_ALLOWANCE_TOO_SMALL"):
riskpool.createBundle(
applicationFilter,
amount,
{'from': riskpoolKeeper})

# ensure bundle cannot be created with too small allowance
testCoin.approve(instance.getTreasury(), 0.5 * amount, {'from': riskpoolKeeper})
with brownie.reverts("ERROR:TRS-053:ALLOWANCE_TOO_SMALL"):
with brownie.reverts("ERROR:TRS-053:CAPITAL_TRANSFER_ALLOWANCE_TOO_SMALL"):
riskpool.createBundle(
applicationFilter,
amount,
Expand Down

0 comments on commit bdaaa6f

Please sign in to comment.