Skip to content

Commit

Permalink
Merge pull request #44 from etherisc/feature/deployer-contract-features
Browse files Browse the repository at this point in the history
Improve deployer contract
  • Loading branch information
doerfli authored Jun 18, 2024
2 parents f36aa15 + d6d7c61 commit 64fa9f0
Show file tree
Hide file tree
Showing 6 changed files with 183 additions and 85 deletions.
143 changes: 67 additions & 76 deletions contracts/Deployer.sol
Original file line number Diff line number Diff line change
@@ -1,27 +1,32 @@
// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8.20;

import {AccessManagerExtendedInitializeable} from "gif-next/contracts/shared/AccessManagerExtendedInitializeable.sol";
import {AmountLib} from "gif-next/contracts/type/Amount.sol";
import {BasicDistribution} from "./BasicDistribution.sol";
import {BasicPool} from "./BasicPool.sol";
import {ChainNft} from "gif-next/contracts/registry/ChainNft.sol";
import {DistributionDeployer} from "./DistributionDeployer.sol";
import {Fee, FeeLib} from "gif-next/contracts/type/Fee.sol";
import {IComponents} from "gif-next/contracts/instance/module/IComponents.sol";
import {IInstance} from "gif-next/contracts/instance/Instance.sol";
import {IInstanceService} from "gif-next/contracts/instance/IInstanceService.sol";
import {IRegistry} from "gif-next/contracts/registry/IRegistry.sol";
import {InstanceReader} from "gif-next/contracts/instance/InstanceReader.sol";
import {InsuranceProduct} from "./InsuranceProduct.sol";
import {INSTANCE} from "gif-next/contracts/type/ObjectType.sol";
import {NftId} from "gif-next/contracts/type/NftId.sol";
import {SecondsLib} from "gif-next/contracts/type/Seconds.sol";
import {PoolDeployer} from "./PoolDeployer.sol";
import {ProductDeployer} from "./ProductDeployer.sol";
import {PRODUCT_OWNER_ROLE, DISTRIBUTION_OWNER_ROLE, POOL_OWNER_ROLE} from "gif-next/contracts/type/RoleId.sol";
import {ReferralLib} from "gif-next/contracts/type/Referral.sol";
import {RiskId, RiskIdLib} from "gif-next/contracts/type/RiskId.sol";
import {SecondsLib} from "gif-next/contracts/type/Seconds.sol";
import {StateId} from "gif-next/contracts/type/StateId.sol";
import {TimestampLib} from "gif-next/contracts/type/Timestamp.sol";
import {UFixedLib} from "gif-next/contracts/type/UFixed.sol";
import {UsdcMock} from "./UsdcMock.sol";
import {IRegistry} from "gif-next/contracts/registry/IRegistry.sol";
import {IInstanceService} from "gif-next/contracts/instance/IInstanceService.sol";
import {INSTANCE} from "gif-next/contracts/type/ObjectType.sol";
import {VersionPart} from "gif-next/contracts/type/Version.sol";
import {AccessManagerExtendedInitializeable} from "gif-next/contracts/shared/AccessManagerExtendedInitializeable.sol";
import {PRODUCT_OWNER_ROLE, DISTRIBUTION_OWNER_ROLE, POOL_OWNER_ROLE} from "gif-next/contracts/type/RoleId.sol";
import {StateId} from "gif-next/contracts/type/StateId.sol";

contract Deployer {

Expand All @@ -33,22 +38,33 @@ contract Deployer {
BasicDistribution private distribution;
BasicPool private pool;
InsuranceProduct private product;
NftId private bundleNftId;
RiskId private riskId;

constructor(
address registryAddress,
string memory deploymentId
)
{
// fetch required components
address theAllmighty = msg.sender;
registry = IRegistry(registryAddress);
IInstanceService instanceService = IInstanceService(registry.getServiceAddress(INSTANCE(), VersionPart.wrap(3)));
(instance, instanceNftId) = instanceService.createInstanceClone();
ChainNft chainNft = ChainNft(registry.getChainNftAddress());
instanceReader = instance.getInstanceReader();

// grant correct roles
AccessManagerExtendedInitializeable instanceAccessManager = instance.getInstanceAccessManager();
instanceAccessManager.grantRole(PRODUCT_OWNER_ROLE().toInt(), address(this), 0);
instanceAccessManager.grantRole(PRODUCT_OWNER_ROLE().toInt(), theAllmighty, 0);
instanceAccessManager.grantRole(DISTRIBUTION_OWNER_ROLE().toInt(), address(this), 0);
instanceAccessManager.grantRole(DISTRIBUTION_OWNER_ROLE().toInt(), theAllmighty, 0);
instanceAccessManager.grantRole(POOL_OWNER_ROLE().toInt(), address(this), 0);
instanceAccessManager.grantRole(POOL_OWNER_ROLE().toInt(), theAllmighty, 0);
Fee memory bundleFee = FeeLib.toFee(UFixedLib.zero(), 0);

// deploy token and components
usdc = new UsdcMock();

distribution = DistributionDeployer.deployDistribution(
Expand All @@ -66,6 +82,7 @@ contract Deployer {
deploymentId,
address(usdc));
pool.register();
pool.approveTokenHandler(AmountLib.max());

product = ProductDeployer.deployProduct(
registryAddress,
Expand All @@ -76,6 +93,33 @@ contract Deployer {
address(pool),
address(distribution));
product.register();


// create a bundle with a coverage of 10k for 30 days
usdc.approve(getPoolTokenHandler(), 10000 * 1000000);
bundleNftId = pool.createBundle(
address(this),
bundleFee,
10000 * 1000000,
SecondsLib.toSeconds(30 * 24 * 60 * 60),
""
);

// create risk
riskId = RiskIdLib.toRiskId("1234");
bytes memory data = "riskdata";
product.createRisk(riskId, data);

// move ownership of instance, component and bundle nfts to instance owner
chainNft.safeTransferFrom(address(this), theAllmighty, instanceNftId.toInt());
chainNft.safeTransferFrom(address(this), theAllmighty, distribution.getNftId().toInt());
chainNft.safeTransferFrom(address(this), theAllmighty, pool.getNftId().toInt());
chainNft.safeTransferFrom(address(this), theAllmighty, product.getNftId().toInt());
chainNft.safeTransferFrom(address(this), theAllmighty, bundleNftId.toInt());

// transfer 10m usdc to owner
usdc.approve(address(this), 10000000000000);
usdc.transferFrom(address(this), theAllmighty, 10000000000000);
}

function getUsdc() public view returns (UsdcMock) {
Expand Down Expand Up @@ -116,21 +160,26 @@ contract Deployer {
return address(productComponentInfo.tokenHandler);
}

function initializeComponents(string memory riskIdStr) public returns (RiskId riskId) {
pool.approveTokenHandler(AmountLib.max());
function getInitialBundleNftId() public view returns (NftId) {
return bundleNftId;
}

function getInitialRiskId() public view returns (RiskId) {
return riskId;
}

function createRisk(string memory riskIdStr, bytes memory data) public returns (RiskId riskId) {
RiskId riskId = RiskIdLib.toRiskId(riskIdStr);
bytes memory data = "riskdata";
product.createRisk(riskId, data);
}

function sendUsdcTokens(address recipient) public {
usdc.transfer(recipient, 1000000);
}

function createBundle(address owner, uint256 amount, uint256 lifetimeInDays) public returns (NftId bundleNftId) {
function createBundle(address owner, uint256 amount, uint256 lifetimeInDays) public returns (NftId newBundleNftId) {
Fee memory bundleFee = FeeLib.toFee(UFixedLib.zero(), 0);
bundleNftId = pool.createBundle(
newBundleNftId = pool.createBundle(
owner,
bundleFee,
amount,
Expand All @@ -151,74 +200,16 @@ contract Deployer {
);
}

function getPolicyState(NftId policyNftId) public view returns (StateId) {
return instanceReader.getPolicyState(policyNftId);
function underwritePolicy(NftId policyNftId) public {
product.underwrite(policyNftId, true, TimestampLib.blockTimestamp());
}

}

library DistributionDeployer {

function deployDistribution(address registry,
NftId instanceNftId,
address initialDistributionOwner,
string memory deploymentId,
address token) public returns (BasicDistribution) {
return new BasicDistribution(
registry,
instanceNftId,
initialDistributionOwner,
string.concat("BasicDistribution", deploymentId),
token,
"",
""
);
function getPolicyState(NftId policyNftId) public view returns (StateId) {
return instanceReader.getPolicyState(policyNftId);
}

}

library PoolDeployer {

function deployPool(address registry,
NftId instanceNftId,
address initialPoolOwner,
string memory deploymentId,
address token) public returns (BasicPool) {
return new BasicPool(
registry,
instanceNftId,
initialPoolOwner,
string.concat("BasicPool", deploymentId),
token,
false,
"",
""
);
function getBundleBalance(NftId bundleNftId) public view returns (uint256) {
return instanceReader.getBalanceAmount(bundleNftId).toInt();
}

}

library ProductDeployer {

function deployProduct(address registry,
NftId instanceNftId,
address initialProductOwner,
string memory deploymentId,
address token,
address poolAddress,
address distributionAddress) public returns (InsuranceProduct) {
return new InsuranceProduct(
registry,
instanceNftId,
initialProductOwner,
string.concat("InsuranceProduct", deploymentId),
token,
false,
poolAddress,
distributionAddress,
"",
""
);
}

}
24 changes: 24 additions & 0 deletions contracts/DistributionDeployer.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8.20;

import {BasicDistribution} from "./BasicDistribution.sol";
import {NftId} from "gif-next/contracts/type/NftId.sol";

library DistributionDeployer {

function deployDistribution(address registry,
NftId instanceNftId,
address initialDistributionOwner,
string memory deploymentId,
address token) public returns (BasicDistribution) {
return new BasicDistribution(
registry,
instanceNftId,
initialDistributionOwner,
string.concat("BasicDistribution", deploymentId),
token,
"",
""
);
}
}
25 changes: 25 additions & 0 deletions contracts/PoolDeployer.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8.20;

import {BasicPool} from "./BasicPool.sol";
import {NftId} from "gif-next/contracts/type/NftId.sol";

library PoolDeployer {

function deployPool(address registry,
NftId instanceNftId,
address initialPoolOwner,
string memory deploymentId,
address token) public returns (BasicPool) {
return new BasicPool(
registry,
instanceNftId,
initialPoolOwner,
string.concat("BasicPool", deploymentId),
token,
false,
"",
""
);
}
}
30 changes: 30 additions & 0 deletions contracts/ProductDeployer.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8.20;

import {InsuranceProduct} from "./InsuranceProduct.sol";
import {NftId} from "gif-next/contracts/type/NftId.sol";


library ProductDeployer {

function deployProduct(address registry,
NftId instanceNftId,
address initialProductOwner,
string memory deploymentId,
address token,
address poolAddress,
address distributionAddress) public returns (InsuranceProduct) {
return new InsuranceProduct(
registry,
instanceNftId,
initialProductOwner,
string.concat("InsuranceProduct", deploymentId),
token,
false,
poolAddress,
distributionAddress,
"",
""
);
}
}
3 changes: 2 additions & 1 deletion scripts/run_deployer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,13 +77,14 @@ async function main() {
distributionOwner,
[
registryAddress!,
"43"
"44"
],
{
"libraries": {
"AmountLib": amountLibAddress,
"FeeLib": feeLibAddress,
"DistributionDeployer": distributionLibAddress,
"NftIdLib": nftIdLibAddress,
"PoolDeployer": poolLibAddress,
"ProductDeployer": productLibAddress,
"ReferralLib": referralLibAddress,
Expand Down
43 changes: 35 additions & 8 deletions test_forge/TestDeployer.t.sol
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
// SPDX-License-Identifier: APACHE-2.0
pragma solidity 0.8.20;

import {APPLIED} from "gif-next/contracts/type/StateId.sol";
import {APPLIED, ACTIVE} from "gif-next/contracts/type/StateId.sol";
import {NftId, NftIdLib} from "gif-next/contracts/type/NftId.sol";
import {RiskId} from "gif-next/contracts/type/RiskId.sol";
import {GifTest} from "gif-next/test/base/GifTest.sol";

import {Deployer} from "../contracts/Deployer.sol";
import {UsdcMock} from "../contracts/UsdcMock.sol";
import {BasicPool} from "../contracts/BasicPool.sol";
import {AmountLib} from "gif-next/contracts/type/Amount.sol";


contract TestDeployer is GifTest {
Expand All @@ -32,19 +34,44 @@ contract TestDeployer is GifTest {
"test123"
);

deployer.sendUsdcTokens(testUser);
RiskId riskId = deployer.initializeComponents("4711");
UsdcMock usdc = deployer.getUsdc();
RiskId riskId = deployer.getInitialRiskId();
NftId newBundleNftId = deployer.getInitialBundleNftId();

usdc.approve(deployer.getPoolTokenHandler(), 10000);
NftId newBundleNftId = deployer.createBundle(testUser, 10000, 30);

NftId policyNftId = deployer.applyForPolicy(testUser, riskId, 1000, 21, newBundleNftId);
NftId policyNftId = deployer.applyForPolicy(testUser, riskId, 1000 * 100000, 21, newBundleNftId);

assertTrue(policyNftId.gtz(), "policyNftId was zero");
assertEq(chainNft.ownerOf(policyNftId.toInt()), testUser, "testUser not owner of policyNftId");

assertTrue(deployer.getPolicyState(policyNftId) == APPLIED(), "state not APPLIED");
}

function test_Deployer_underwrite() public {
address testUser = makeAddr("testUser");

// GIVEN
vm.startPrank(registryOwner);
token.transfer(testUser, 1000000);
vm.stopPrank();

vm.startPrank(testUser);

Deployer deployer = new Deployer(
address(registry),
"test123"
);

RiskId riskId = deployer.getInitialRiskId();
NftId newBundleNftId = deployer.getInitialBundleNftId();

NftId policyNftId = deployer.applyForPolicy(testUser, riskId, 1000 * 100000, 14, newBundleNftId);
assertTrue(policyNftId.gtz(), "policyNftId was zero");
assertEq(chainNft.ownerOf(policyNftId.toInt()), testUser, "testUser not owner of policyNftId");

UsdcMock usdc = UsdcMock(deployer.getUsdc());
usdc.approve(deployer.getProductTokenHandler(), 100 * 1000000);
deployer.underwritePolicy(policyNftId);

assertTrue(deployer.getPolicyState(policyNftId) == ACTIVE(), "state not ACTIVE");
}

}

0 comments on commit 64fa9f0

Please sign in to comment.