Skip to content

Commit

Permalink
add burning for riskpool bundles
Browse files Browse the repository at this point in the history
  • Loading branch information
matthiaszimmermann committed Jul 18, 2022
1 parent b05e641 commit a93a58a
Show file tree
Hide file tree
Showing 10 changed files with 250 additions and 82 deletions.
5 changes: 2 additions & 3 deletions brownie-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,7 @@ compiler:
# https://eth-brownie.readthedocs.io/en/stable/compile.html#compiler-settings
remappings:
- "@openzeppelin=OpenZeppelin/[email protected]"
- "@gif-interface=etherisc/[email protected]"
- "@etherisc/gif-interface=etherisc/[email protected]"
- "@etherisc/gif-interface=etherisc/[email protected]"
vyper:
version: null

Expand All @@ -23,7 +22,7 @@ compiler:
dependencies:
# github dependency format: <owner>/<repository>@<release>
- OpenZeppelin/[email protected]
- etherisc/gif-interface@1.7.0-staging-k
- etherisc/gif-interface@1.8.0-staging-f

# exclude Ownable when calculating test coverage
# https://eth-brownie.readthedocs.io/en/v1.10.3/config.html#exclude_paths
Expand Down
62 changes: 42 additions & 20 deletions contracts/modules/BundleController.sol
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,7 @@ contract BundleController is
emit LogBundleCreated(bundle.id, riskpoolId_, owner_, bundle.state, bundle.capital);
}

// TODO decide + implement authz for risk bundle creation
// funding can come from nft owner or various 2nd level risk pool owners

function fund(uint256 bundleId, uint256 amount)
external override
onlyRiskpoolService
Expand All @@ -87,18 +86,22 @@ contract BundleController is
emit LogBundleCapitalProvided(bundleId, _msgSender(), amount, capacityAmount);
}


function defund(uint256 bundleId, uint256 amount)
external override
onlyRiskpoolService
{
Bundle storage bundle = _bundles[bundleId];
require(bundle.createdAt > 0, "ERROR:BUC-013:BUNDLE_DOES_NOT_EXIST");
require(
bundle.capital >= bundle.lockedCapital + amount,
"ERROR:BUC-014:CAPACITY_TOO_LOW"
bundle.capital >= bundle.lockedCapital + amount
|| (bundle.lockedCapital == 0 && bundle.balance >= amount),
"ERROR:BUC-014:CAPACITY_OR_BALANCE_TOO_LOW"
);

bundle.capital -= amount;
if (bundle.capital >= amount) { bundle.capital -= amount; }
else { bundle.capital = 0; }

bundle.balance -= amount;
bundle.updatedAt = block.timestamp;

Expand Down Expand Up @@ -128,14 +131,28 @@ contract BundleController is
_changeState(bundleId, BundleState.Closed);
}

function burn(uint256 bundleId)
external override
onlyRiskpoolService
{
Bundle storage bundle = _bundles[bundleId];
require(bundle.state == BundleState.Closed, "ERROR:BUC-016:BUNDLE_NOT_CLOSED");
require(bundle.balance == 0, "ERROR:BUC-016:BUNDLE_HAS_BALANCE");

// burn corresponding nft -> as a result bundle looses its owner
_token.burn(bundleId);

_changeState(bundleId, BundleState.Burned);
}

function collateralizePolicy(uint256 bundleId, bytes32 processId, uint256 amount)
external override
onlyRiskpoolService
{
Bundle storage bundle = _bundles[bundleId];
require(bundle.createdAt > 0, "ERROR:BUC-001:BUNDLE_DOES_NOT_EXIST");
require(bundle.state == IBundle.BundleState.Active, "ERROR:BUC-005:BUNDLE_NOT_ACTIVE");
require(bundle.capital >= bundle.lockedCapital + amount, "ERROR:BUC-006:CAPACITY_TOO_LOW");
require(bundle.createdAt > 0, "ERROR:BUC-020:BUNDLE_DOES_NOT_EXIST");
require(bundle.state == IBundle.BundleState.Active, "ERROR:BUC-021:BUNDLE_NOT_ACTIVE");
require(bundle.capital >= bundle.lockedCapital + amount, "ERROR:BUC-022:CAPACITY_TOO_LOW");

bundle.lockedCapital += amount;
bundle.updatedAt = block.timestamp;
Expand All @@ -155,16 +172,16 @@ contract BundleController is
{
// make sure bundle exists and is not yet closed
Bundle storage bundle = _bundles[bundleId];
require(bundle.createdAt > 0, "ERROR:BUC-001:BUNDLE_DOES_NOT_EXIST");
require(_activePolicies[bundleId] > 0, "ERROR:BUC-007:NO_ACTIVE_POLICIES_FOR_BUNDLE");
require(bundle.createdAt > 0, "ERROR:BUC-023:BUNDLE_DOES_NOT_EXIST");
require(_activePolicies[bundleId] > 0, "ERROR:BUC-024:NO_ACTIVE_POLICIES_FOR_BUNDLE");

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

// this should never ever fail ...
require(
bundle.lockedCapital >= collateralAmount,
"PANIC:BUC-008:UNLOCK_CAPITAL_TOO_BIG"
"PANIC:BUC-026:UNLOCK_CAPITAL_TOO_BIG"
);

// policy no longer relevant for bundle
Expand All @@ -185,8 +202,8 @@ contract BundleController is
onlyRiskpoolService
{
Bundle storage bundle = _bundles[bundleId];
require(bundle.createdAt > 0, "ERROR:BUC-001:BUNDLE_DOES_NOT_EXIST");
require(bundle.state != IBundle.BundleState.Closed, "ERROR:BUC-005:BUNDLE_CLOSED");
require(bundle.createdAt > 0, "ERROR:BUC-031:BUNDLE_DOES_NOT_EXIST");
require(bundle.state != IBundle.BundleState.Closed, "ERROR:BUC-032:BUNDLE_CLOSED");

bundle.balance += amount;
bundle.updatedAt = block.timestamp;
Expand All @@ -198,7 +215,7 @@ contract BundleController is
onlyRiskpoolService
{
Bundle storage bundle = _bundles[bundleId];
require(bundle.createdAt > 0, "ERROR:BUC-001:BUNDLE_DOES_NOT_EXIST");
require(bundle.createdAt > 0, "ERROR:BUC-033:BUNDLE_DOES_NOT_EXIST");

revert("NOT_IMPLEMENTED_YET:decreaseBalance(...)");
}
Expand Down Expand Up @@ -236,7 +253,7 @@ contract BundleController is

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

Expand Down Expand Up @@ -266,17 +283,22 @@ contract BundleController is
if (oldState == BundleState.Active) {
require(
newState == BundleState.Locked || newState == BundleState.Closed,
"ERROR:BUC-013:ACTIVE_INVALID_TRANSITION"
"ERROR:BUC-050:ACTIVE_INVALID_TRANSITION"
);
} else if (oldState == BundleState.Locked) {
require(
newState == BundleState.Active || newState == BundleState.Closed,
"ERROR:BUC-013:LOCKED_INVALID_TRANSITION"
"ERROR:BUC-051:LOCKED_INVALID_TRANSITION"
);
} else if (oldState == BundleState.Closed) {
revert("ERROR:BUC-014:CLOSED_IS_FINAL_STATE");
require(
newState == BundleState.Burned,
"ERROR:BUC-052:CLOSED_INVALID_TRANSITION"
);
} else if (oldState == BundleState.Burned) {
revert("ERROR:BUC-053:BURNED_IS_FINAL_STATE");
} else {
revert("ERROR:BOC-018:INITIAL_STATE_NOT_HANDLED");
revert("ERROR:BOC-054:INITIAL_STATE_NOT_HANDLED");
}
}

Expand Down
23 changes: 12 additions & 11 deletions contracts/modules/TreasuryModule.sol
Original file line number Diff line number Diff line change
Expand Up @@ -234,11 +234,11 @@ contract TreasuryModule is
emit LogTreasuryCapitalProcessed(bundle.riskpoolId, bundleId, capitalAmount, success);
}

// TODO remove once at ITreasury
event LogTreasuryWithdrawlTransferred(address riskpoolWalletAddress, address to, uint256 amount, bool success);
event LogTreasuryWithdrawlProcessed(uint256 riskpoolId, uint256 bundleId, uint256 amount, bool success);
// // TODO cleanup remove once at ITreasury
// event LogTreasuryWithdrawalTransferred(address riskpoolWalletAddress, address to, uint256 amount, bool success);
// event LogTreasuryWithdrawalProcessed(uint256 riskpoolId, uint256 bundleId, uint256 amount, bool success);

function processWithdrawl(uint256 bundleId, uint256 amount)
function processWithdrawal(uint256 bundleId, uint256 amount)
external override
returns(
bool success,
Expand All @@ -248,8 +248,9 @@ contract TreasuryModule is
// obtain relevant bundle info
IBundle.Bundle memory bundle = _bundle.getBundle(bundleId);
require(
bundle.capital >= bundle.lockedCapital + amount,
"ERROR:TRS-002:CAPACITY_SMALLER_THAN_WITHDRAWL"
bundle.capital >= bundle.lockedCapital + amount
|| (bundle.lockedCapital == 0 && bundle.balance >= amount),
"ERROR:TRS-002:CAPACITY_OR_BALANCE_SMALLER_THAN_WITHDRAWAL"
);

// obtain relevant token for product/riskpool pair
Expand All @@ -260,17 +261,17 @@ contract TreasuryModule is
token.allowance(
riskpoolWallet,
address(this)) >= amount,
"ERROR:TRS-002:ALLOWANCE_SMALLER_THAN_WITHDRAWL"
"ERROR:TRS-002:ALLOWANCE_SMALLER_THAN_WITHDRAWAL"
);

// TODO consider to introduce withdrawl fees
// TODO consider to introduce withdrawal fees
netAmount = amount;
success = token.transferFrom(riskpoolWallet, bundleOwner, netAmount);

emit LogTreasuryWithdrawlTransferred(riskpoolWallet, bundleOwner, netAmount, success);
require(success, "ERROR:TRS-002:WITHDRAWL_TRANSFER_FAILED");
emit LogTreasuryWithdrawalTransferred(riskpoolWallet, bundleOwner, netAmount, success);
require(success, "ERROR:TRS-002:WITHDRAWAL_TRANSFER_FAILED");

emit LogTreasuryWithdrawlProcessed(bundle.riskpoolId, bundleId, netAmount, success);
emit LogTreasuryWithdrawalProcessed(bundle.riskpoolId, bundleId, netAmount, success);
}


Expand Down
58 changes: 40 additions & 18 deletions contracts/services/RiskpoolService.sol
Original file line number Diff line number Diff line change
Expand Up @@ -72,12 +72,13 @@ contract RiskpoolService is

function fundBundle(uint256 bundleId, uint256 amount)
external override
onlyOwningRiskpool(bundleId)
onlyOwningRiskpool(bundleId)
returns(bool success, uint256 netAmount)
{
IBundle.Bundle memory bundle = _bundle.getBundle(bundleId);
require(bundle.state != IBundle.BundleState.Closed, "ERROR:RPS-003:BUNDLE_CLOSED");

(bool success, uint256 netAmount) = _treasury.processCapital(bundleId, amount);
(success, netAmount) = _treasury.processCapital(bundleId, amount);
if (success) {
_bundle.fund(bundleId, netAmount);
}
Expand All @@ -86,11 +87,15 @@ contract RiskpoolService is

function defundBundle(uint256 bundleId, uint256 amount)
external override
onlyOwningRiskpool(bundleId)
onlyOwningRiskpool(bundleId)
returns(bool success, uint256 netAmount)
{
(bool success, uint256 netAmount) = _treasury.processWithdrawl(bundleId, amount);
(success, netAmount) = _treasury.processWithdrawal(bundleId, amount);
require(success, "ERROR:RPS-004:BUNDLE_DEFUNDING_FAILED");
require(netAmount == amount, "UUPS");

if (success) {
_bundle.defund(bundleId, netAmount);
_bundle.defund(bundleId, amount);
}
}

Expand Down Expand Up @@ -118,28 +123,29 @@ contract RiskpoolService is
_bundle.close(bundleId);
}


function collateralizePolicy(uint256 bundleId, bytes32 processId, uint256 collateralAmount)
function burnBundle(uint256 bundleId)
external override
onlyOwningRiskpool(bundleId)
{
_bundle.collateralizePolicy(bundleId, processId, collateralAmount);
}
// ensure bundle is closed
IBundle.Bundle memory bundle = _bundle.getBundle(bundleId);
require(bundle.state == IBundle.BundleState.Closed, "ERROR:RPS-004:BUNDLE_NOT_CLOSED");

// withdraw remaining balance
(bool success, uint256 netAmount) = _treasury.processWithdrawal(bundleId, bundle.balance);
require(success, "ERROR:RPS-005:WITHDRAWAL_FAILED");

function increaseBundleBalance(uint256 bundleId, bytes32 processId, uint256 amount)
external override
onlyOwningRiskpool(bundleId)
{
_bundle.increaseBalance(bundleId, processId, amount);
if (success) {
_bundle.defund(bundleId, bundle.balance);
_bundle.burn(bundleId);
}
}


function decreaseBundleBalance(uint256 bundleId, bytes32 processId, uint256 amount)

function collateralizePolicy(uint256 bundleId, bytes32 processId, uint256 collateralAmount)
external override
onlyOwningRiskpool(bundleId)
{
revert("NOT_IMPLEMENTED_YET:decreaseBundleBalance(...)");
_bundle.collateralizePolicy(bundleId, processId, collateralAmount);
}

function releasePolicy(uint256 bundleId, bytes32 processId)
Expand All @@ -157,4 +163,20 @@ contract RiskpoolService is

collateralAmount = _bundle.releasePolicy(bundleId, processId);
}


function increaseBundleBalance(uint256 bundleId, bytes32 processId, uint256 amount)
external override
onlyOwningRiskpool(bundleId)
{
_bundle.increaseBalance(bundleId, processId, amount);
}


function decreaseBundleBalance(uint256 bundleId, bytes32 processId, uint256 amount)
external override
onlyOwningRiskpool(bundleId)
{
revert("NOT_IMPLEMENTED_YET:decreaseBundleBalance(...)");
}
}
1 change: 1 addition & 0 deletions contracts/test/TestProduct.sol
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import "@etherisc/gif-interface/contracts/modules/IPolicy.sol";
import "@etherisc/gif-interface/contracts/services/IProductService.sol";
import "@etherisc/gif-interface/contracts/services/IInstanceService.sol";
import "@etherisc/gif-interface/contracts/components/Product.sol";

import "@openzeppelin/contracts/token/ERC20/ERC20.sol";

contract TestProduct is
Expand Down
10 changes: 8 additions & 2 deletions scripts/setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,20 @@
def fund_riskpool(
instance: GifInstance,
owner: Account,
capitalOwner: Account,
riskpool,
bundleOwner: Account,
coin,
amount: int
):
# transfer funds to riskpool keeper and create allowance
coin.transfer(bundleOwner, amount, {'from': owner})
coin.approve(instance.getTreasury(), amount, {'from': bundleOwner})
safetyFactor = 2
coin.transfer(bundleOwner, safetyFactor * amount, {'from': owner})
coin.approve(instance.getTreasury(), safetyFactor * amount, {'from': bundleOwner})

# create approval for treasury from capital owner to allow for withdrawls
maxUint256 = 2**256-1
coin.approve(instance.getTreasury(), maxUint256, {'from': capitalOwner})

applicationFilter = bytes(0)
riskpool.createBundle(
Expand Down
Loading

0 comments on commit a93a58a

Please sign in to comment.