Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add unique processId creation in PolicyController, adapt+amend tests #17

Merged
merged 1 commit into from
Aug 9, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 9 additions & 2 deletions brownie-config.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
# secrets management via .env (excluded via .gitignore)
dotenv: .env

networks:
default: development
development:
cmd_settings:
# without this explicit setting chainid==1 is returend by block.chainid
chain_id: 1337

# brownie default values made explicit
compiler:
evm_version: null
Expand All @@ -15,7 +22,7 @@ compiler:
remappings:
- "@openzeppelin=OpenZeppelin/openzeppelin-contracts@4.7.0"
- "@chainlink=smartcontractkit/chainlink@1.6.0"
- "@etherisc/gif-interface=etherisc/gif-interface@2.0.0-staging-o"
- "@etherisc/gif-interface=etherisc/gif-interface@b04fd3e"

# packages below will be added to brownie
# you may use 'brownie pm list' after 'brownie compile'
Expand All @@ -24,7 +31,7 @@ dependencies:
# github dependency format: <owner>/<repository>@<release>
- OpenZeppelin/openzeppelin-contracts@4.7.0
- smartcontractkit/chainlink@1.6.0
- etherisc/gif-interface@2.0.0-staging-o
- etherisc/gif-interface@b04fd3e

# exclude Ownable when calculating test coverage
# https://eth-brownie.readthedocs.io/en/v1.10.3/config.html#exclude_paths
Expand Down
11 changes: 1 addition & 10 deletions contracts/examples/AyiiProduct.sol
Original file line number Diff line number Diff line change
Expand Up @@ -133,13 +133,11 @@ contract AyiiProduct is
require(risk.createdAt > 0, "ERROR:AYI-002:RISK_UNDEFINED");
require(policyHolder != address(0), "ERROR:AYI-003:POLICY_HOLDER_ZERO");

processId = uniqueId(policyHolder);
bytes memory metaData = "";
bytes memory applicationData = abi.encode(riskId);

_newApplication(
processId = _newApplication(
policyHolder,
processId,
premium,
sumInsured,
metaData,
Expand Down Expand Up @@ -339,13 +337,6 @@ contract AyiiProduct is
return a <= b ? a : b;
}

function uniqueId(address _addr)
internal
returns (bytes32 _uniqueId)
{
return keccak256(abi.encode(_addr, _applications.length));
}

function getRisk(bytes32 riskId)
external
view
Expand Down
4 changes: 2 additions & 2 deletions contracts/flows/PolicyDefaultFlow.sol
Original file line number Diff line number Diff line change
Expand Up @@ -53,19 +53,19 @@ contract PolicyDefaultFlow is

function newApplication(
address owner,
bytes32 processId,
uint256 premiumAmount,
uint256 sumInsuredAmount,
bytes calldata metaData,
bytes calldata applicationData
)
external
returns(bytes32 processId)
{
ILicense license = getLicenseContract();
uint256 productId = license.getProductId(msg.sender);

IPolicy policy = getPolicyContract();
policy.createPolicyFlow(owner, processId, productId, metaData);
processId = policy.createPolicyFlow(owner, productId, metaData);
policy.createApplication(
processId,
premiumAmount,
Expand Down
20 changes: 16 additions & 4 deletions contracts/modules/PolicyController.sol
Original file line number Diff line number Diff line change
Expand Up @@ -31,18 +31,19 @@ contract PolicyController is
mapping(bytes32 => mapping(uint256 => Payout)) public payouts;
mapping(bytes32 => uint256) public payoutCount;

bytes32[] private _processIds;
uint256 private _processIds;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This name should be changed to _processId or _lastProcessId.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

renamed member to "_assignedProcessIds", committed on master


/* Metadata */
function createPolicyFlow(
address owner,
bytes32 processId,
uint256 productId,
bytes calldata data
)
external override
onlyPolicyFlow("Policy")
returns(bytes32 processId)
{
processId = _generateNextProcessId();
Metadata storage meta = metadata[processId];
require(meta.createdAt == 0, "ERROR:POC-001:METADATA_ALREADY_EXISTS");

Expand All @@ -52,7 +53,6 @@ contract PolicyController is
meta.data = data;
meta.createdAt = block.timestamp;
meta.updatedAt = block.timestamp;
_processIds.push(processId);

emit LogMetadataCreated(owner, processId, productId, PolicyFlowState.Started);
}
Expand Down Expand Up @@ -442,6 +442,18 @@ contract PolicyController is
}

function processIds() external view returns (uint256) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be changed accordingly

return _processIds.length;
return _processIds;
}

function _generateNextProcessId() private returns(bytes32 processId) {
_processIds += 1;

processId = keccak256(
abi.encodePacked(
block.chainid,
address(_registry),
_processIds
)
);
}
}
33 changes: 23 additions & 10 deletions contracts/services/InstanceService.sol
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,10 @@ contract InstanceService is
IInstanceService,
CoreController
{
bytes32 public constant BUNDLE_NAME = "Bundle";
bytes32 public constant COMPONENT_NAME = "Component";
bytes32 public constant POLICY_NAME = "Policy";
bytes32 public constant BUNDLE_NAME = "Bundle";
bytes32 public constant TREASURY_NAME = "Treasury";

bytes32 public constant COMPONENT_OWNER_SERVICE_NAME = "ComponentOwnerService";
bytes32 public constant INSTANCE_OPERATOR_SERVICE_NAME = "InstanceOperatorService";
Expand All @@ -42,12 +43,29 @@ contract InstanceService is
TreasuryModule private _treasury;

function _afterInitialize() internal override onlyInitializing {
_bundle = BundleController(_getContractAddress("Bundle"));
_component = ComponentController(_getContractAddress("Component"));
_policy = PolicyController(_getContractAddress("Policy"));
_treasury = TreasuryModule(_getContractAddress("Treasury"));
_bundle = BundleController(_getContractAddress(BUNDLE_NAME));
_component = ComponentController(_getContractAddress(COMPONENT_NAME));
_policy = PolicyController(_getContractAddress(POLICY_NAME));
_treasury = TreasuryModule(_getContractAddress(TREASURY_NAME));
}

/* instance service */
function getChainId() public view returns(uint256 chainId) {
chainId = block.chainid;
}

function getInstanceId() public view returns(bytes32 instanceId) {
instanceId = keccak256(
abi.encodePacked(
block.chainid,
address(_registry)));
}

function getInstanceOperator() external override view returns(address) {
InstanceOperatorService ios = InstanceOperatorService(_getContractAddress(INSTANCE_OPERATOR_SERVICE_NAME));
return ios.owner();
}

/* registry */
function getComponentOwnerService() external override view returns(IComponentOwnerService service) {
return IComponentOwnerService(_getContractAddress(COMPONENT_OWNER_SERVICE_NAME));
Expand All @@ -69,11 +87,6 @@ contract InstanceService is
return IRiskpoolService(_getContractAddress(RISKPOOL_SERVICE_NAME));
}

function getOwner() external override view returns(address) {
InstanceOperatorService ios = InstanceOperatorService(_getContractAddress(INSTANCE_OPERATOR_SERVICE_NAME));
return ios.owner();
}

// TODO decide how to protect registry access
function getRegistry() external view returns(IRegistry service) {
return _registry;
Expand Down
5 changes: 1 addition & 4 deletions contracts/test/TestCompromisedProduct.sol
Original file line number Diff line number Diff line change
Expand Up @@ -91,11 +91,8 @@ contract TestCompromisedProduct is
address payable policyHolder = payable(_msgSender());

// Create and underwrite new application
processId = keccak256(abi.encode(policyHolder, _policies));

_productService.newApplication(
processId = _productService.newApplication(
policyHolder,
processId,
premium,
sumInsured,
metaData,
Expand Down
6 changes: 1 addition & 5 deletions contracts/test/TestProduct.sol
Original file line number Diff line number Diff line change
Expand Up @@ -56,12 +56,8 @@ contract TestProduct is
{
address payable policyHolder = payable(_msgSender());

// Create and underwrite new application
processId = keccak256(abi.encode(policyHolder, _policies));

_newApplication(
processId = _newApplication(
policyHolder,
processId,
premium,
sumInsured,
metaData,
Expand Down
68 changes: 68 additions & 0 deletions tests/test_apply_underwrite_expire.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import brownie
import pytest

from web3 import Web3

from brownie.network.account import Account
from brownie import (
interface,
Expand Down Expand Up @@ -37,6 +39,72 @@
def isolation(fn_isolation):
pass

def test_process_id_creation(
instance: GifInstance,
testCoin,
gifTestProduct: GifTestProduct,
riskpoolKeeper: Account,
owner: Account,
customer: Account,
capitalOwner: Account
):
# prepare funded riskpool
riskpool = gifTestProduct.getRiskpool().getContract()
initialFunding = 15000
fund_riskpool(instance, owner, capitalOwner, riskpool, riskpoolKeeper, testCoin, initialFunding)

# record number of policies before policy creation
product = gifTestProduct.getContract()

# application spec
premium = 100
sumInsured = 5000
metaData = bytes(0)
applicationData = bytes(0)

# transfer funds to customer and create allowance
testCoin.transfer(customer, 2 * premium, {'from': owner})
testCoin.approve(instance.getTreasury(), 2 * premium, {'from': customer})

instanceService = instance.getInstanceService()
chainId = Web3().eth.chain_id
registryAddress = instanceService.getRegistry()

# compute expected process id values
expectedProcessId1 = Web3.solidityKeccak(
['uint256', 'address', 'uint256'],
[chainId, registryAddress, product.policies() + 1]).hex()

expectedProcessId2 = Web3.solidityKeccak(
['uint256', 'address', 'uint256'],
[chainId, registryAddress, product.policies() + 2]).hex()

# create policies
tx1 = product.applyForPolicy(
premium,
sumInsured,
metaData,
applicationData,
{'from': customer})

tx2 = product.applyForPolicy(
premium,
sumInsured,
metaData,
applicationData,
{'from': customer})

assert product.policies() == 2

processId1 = tx1.return_value
processId2 = tx2.return_value

assert processId1 != expectedProcessId2
assert processId1 == expectedProcessId1
assert processId2 == expectedProcessId2



def test_create_policy(
instance: GifInstance,
testCoin,
Expand Down
2 changes: 1 addition & 1 deletion tests/test_deploy_instance.py
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ def test_InstanceService(instance, registry, owner):
instanceService = instance.getInstanceService()

assert instanceService.address == registry.getContract(s2b32(INSTANCE_SERVICE_NAME))
assert instanceService.getOwner() == owner
assert instanceService.getInstanceOperator() == owner
assert owner != 0x0

with pytest.raises(AttributeError):
Expand Down
21 changes: 21 additions & 0 deletions tests/test_instance_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
import brownie
import pytest

from web3 import Web3

from brownie import (
InstanceService,
interface
Expand All @@ -22,6 +24,25 @@
s2b32,
)


def test_get_chain_id(instance):
w3 = Web3()
instanceService = instance.getInstanceService()
assert instanceService.getChainId() == w3.eth.chain_id


def test_get_instance_id(instance):
instanceService = instance.getInstanceService()
registryAddress = instanceService.getRegistry()

gifInstanceId = instanceService.getInstanceId()
web3keccak = Web3.solidityKeccak(
['uint256', 'address'],
[instanceService.getChainId(), registryAddress]).hex()

assert gifInstanceId == web3keccak


def test_services_against_registry(instance, owner):
instanceService = instance.getInstanceService()
registryAddress = instanceService.getRegistry()
Expand Down