Skip to content

Commit

Permalink
fix multiple policies linked to single flight
Browse files Browse the repository at this point in the history
  • Loading branch information
matthiaszimmermann committed Oct 14, 2024
1 parent bc9951f commit 75399e4
Show file tree
Hide file tree
Showing 8 changed files with 283 additions and 103 deletions.
9 changes: 8 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,13 @@ forge test
hh run scripts/deploy_gif.ts
```

For a non-local deployment add the `--network` switch.
The available network names are defined in `hardhat.config.ts`.

```bash
hh run scripts/deploy_gif.ts --network polygonAmoy
```

To include the fire example components instead run the following command

```bash
Expand All @@ -76,7 +83,7 @@ This uses the same environment variables as the deployment script.
- `RESUMEABLE_DEPLOYMENT` if this flag is set to `true`, the deployment will write all transactions to a state file so the deployment can be resumed after a failure (or after a manual stop). data is stored in the `deployment/<chainid>/` directory.
- `ETHERSCAN_API_KEY` the api key for etherscan
- `POLYGONSCAN_API_KEY` the api key for polygonscan

- `WRITE_ADDRESSES_TO_FILE` dumps all deployed addresses to file `deployment.env`

## Hardhat commands

Expand Down
21 changes: 0 additions & 21 deletions contracts/authorization/AccessAdmin.sol
Original file line number Diff line number Diff line change
Expand Up @@ -657,25 +657,4 @@ contract AccessAdmin is
AccessAdminLib.toFunctionGrantingString(this, func.name, roleId),
lastUpdateIn);
}


// TODO cleanup
// function _checkAuthorization(
// address authorization,
// ObjectType expectedDomain,
// VersionPart expectedRelease,
// bool expectServiceAuthorization,
// bool checkAlreadyInitialized
// )
// internal
// view
// {
// AccessAdminLib.checkAuthorization(
// _authorization,
// authorization,
// expectedDomain,
// expectedRelease,
// expectServiceAuthorization,
// checkAlreadyInitialized);
// }
}
9 changes: 9 additions & 0 deletions contracts/examples/flight/FlightOracle.sol
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,15 @@ contract FlightOracle is
}


function isActiveRequest(RequestId requestId)
external
view
returns(bool isActive)
{
return LibRequestIdSet.contains(_activeRequests, requestId);
}


function getRequestState(RequestId requestId)
external
view
Expand Down
172 changes: 100 additions & 72 deletions contracts/examples/flight/FlightProduct.sol
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ import {ReferralLib} from "../../type/Referral.sol";
import {RiskId, RiskIdLib} from "../../type/RiskId.sol";
import {RequestId} from "../../type/RequestId.sol";
import {Seconds, SecondsLib} from "../../type/Seconds.sol";
import {Str} from "../../type/String.sol";
import {Str, StrLib} from "../../type/String.sol";
import {Timestamp, TimestampLib} from "../../type/Timestamp.sol";


Expand Down Expand Up @@ -66,6 +66,8 @@ contract FlightProduct is

bool internal _testMode;

mapping(RiskId riskId => RequestId requestId) internal _requests;

// GIF V3 specifics
NftId internal _defaultBundleNftId;
NftId internal _oracleNftId;
Expand All @@ -88,7 +90,7 @@ contract FlightProduct is


struct ApplicationData {
Str flightData;
string flightData;
Timestamp departureTime;
string departureTimeLocal;
Timestamp arrivalTime;
Expand Down Expand Up @@ -137,6 +139,7 @@ contract FlightProduct is
getNftId()).oracleNftId[0];
}


function calculatePayoutAmounts(
FlightProduct flightProduct,
Amount premium,
Expand Down Expand Up @@ -182,7 +185,7 @@ contract FlightProduct is
policyNftId
) = _createPolicy(
policyHolder,
application.flightData,
StrLib.toStr(application.flightData),
application.departureTime,
application.departureTimeLocal,
application.arrivalTime,
Expand All @@ -192,68 +195,6 @@ contract FlightProduct is
}


function _createPolicy(
address policyHolder,
Str flightData,
Timestamp departureTime,
string memory departureTimeLocal,
Timestamp arrivalTime,
string memory arrivalTimeLocal,
Amount premiumAmount,
uint256[6] memory statistics
)
internal
virtual
returns (
RiskId riskId,
NftId policyNftId
)
{
// checks
// disabled for now - using rbac for security
FlightLib.checkApplicationData(
this,
flightData,
departureTime,
arrivalTime,
premiumAmount);

(riskId, policyNftId) = _prepareApplication(
policyHolder,
flightData,
departureTime,
departureTimeLocal,
arrivalTime,
arrivalTimeLocal,
premiumAmount,
statistics);

_createPolicy(
policyNftId,
TimestampLib.zero(), // do not ativate yet
premiumAmount); // max premium amount

// interactions (token transfer + callback to token holder, if contract)
_collectPremium(
policyNftId,
departureTime); // activate at scheduled departure time of flight

// send oracle request for flight status (interacts with flight oracle contract)
_sendRequest(
_oracleNftId,
abi.encode(
FlightOracle.FlightStatusRequest(
riskId,
flightData,
departureTime)),
// allow up to 30 days to process the claim
arrivalTime.addSeconds(SecondsLib.fromDays(30)),
"flightStatusCallback");

emit LogFlightPolicyPurchased(policyNftId, flightData.toString(), premiumAmount);
}


/// @dev Callback for flight status oracle.
/// Function may only be alled by oracle service.
function flightStatusCallback(
Expand Down Expand Up @@ -355,6 +296,27 @@ contract FlightProduct is

function getOracleNftId() public view returns (NftId oracleNftId) { return _oracleNftId; }
function isTestMode() public view returns (bool) { return _testMode; }


function getFlightRisk(
RiskId riskId,
bool requireRiskExists
)
public
view
returns (
bool exists,
FlightRisk memory flightRisk
)
{
(exists, flightRisk) = FlightLib.getFlightRisk(
_getInstanceReader(),
getNftId(),
riskId,
requireRiskExists);
}

function getRequestForRisk(RiskId riskId) public view returns (RequestId requestId) { return _requests[riskId]; }
function decodeFlightRiskData(bytes memory data) public pure returns (FlightRisk memory) { return abi.decode(data, (FlightRisk)); }

//--- internal functions ------------------------------------------------//
Expand All @@ -381,6 +343,70 @@ contract FlightProduct is
}


function _createPolicy(
address policyHolder,
Str flightData,
Timestamp departureTime,
string memory departureTimeLocal,
Timestamp arrivalTime,
string memory arrivalTimeLocal,
Amount premiumAmount,
uint256[6] memory statistics
)
internal
virtual
returns (
RiskId riskId,
NftId policyNftId
)
{
// checks
// disabled for now - using rbac for security
FlightLib.checkApplicationData(
this,
flightData,
departureTime,
arrivalTime,
premiumAmount);

(riskId, policyNftId) = _prepareApplication(
policyHolder,
flightData,
departureTime,
departureTimeLocal,
arrivalTime,
arrivalTimeLocal,
premiumAmount,
statistics);

_createPolicy(
policyNftId,
TimestampLib.zero(), // do not ativate yet
premiumAmount); // max premium amount

// interactions (token transfer + callback to token holder, if contract)
_collectPremium(
policyNftId,
departureTime); // activate at scheduled departure time of flight

// send oracle request for for new risk to obtain flight status (interacts with flight oracle contract)
if (_requests[riskId].eqz()) {
_requests[riskId] = _sendRequest(
_oracleNftId,
abi.encode(
FlightOracle.FlightStatusRequest(
riskId,
flightData,
departureTime)),
// allow up to 30 days to process the claim
arrivalTime.addSeconds(SecondsLib.fromDays(30)),
"flightStatusCallback");
}

emit LogFlightPolicyPurchased(policyNftId, flightData.toString(), premiumAmount);
}


function _prepareApplication(
address policyHolder,
Str flightData,
Expand Down Expand Up @@ -518,11 +544,7 @@ contract FlightProduct is
virtual
{
// check risk exists
InstanceReader reader = _getInstanceReader();
(
bool exists,
FlightRisk memory flightRisk
) = FlightLib.getFlightRisk(reader, getNftId(), riskId, true);
(, FlightRisk memory flightRisk) = getFlightRisk(riskId, true);

// update status, if not yet set
if (flightRisk.statusUpdatedAt.eqz()) {
Expand Down Expand Up @@ -568,9 +590,15 @@ contract FlightProduct is
uint256 policiesToProcess = reader.policiesForRisk(riskId);
uint256 policiesProcessed = policiesToProcess < maxPoliciesToProcess ? policiesToProcess : maxPoliciesToProcess;

// go trough policies
// assemble array with policies to process
NftId [] memory policies = new NftId[](policiesProcessed);
for (uint256 i = 0; i < policiesProcessed; i++) {
policies[i] = reader.getPolicyForRisk(riskId, i);
}

// go through policies
for (uint256 i = 0; i < policiesProcessed; i++) {
NftId policyNftId = reader.getPolicyForRisk(riskId, i);
NftId policyNftId = policies[i];
Amount payoutAmount = FlightLib.getPayoutAmount(
reader.getPolicyInfo(policyNftId).applicationData,
payoutOption);
Expand Down
12 changes: 10 additions & 2 deletions contracts/examples/flight/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ From `hh console --network <name>`
```js
[protocolOwner,masterInstanceOwner,flightOwner] = await ethers.getSigners();

// check balance
ethers.formatEther(await ethers.provider.getBalance(flightOwner))

flightUSD = await hre.ethers.getContractAt("FlightUSD", process.env.FLIGHT_TOKEN_ADDRESS, flightOwner);
chainNft = await hre.ethers.getContractAt("ChainNft", process.env.CHAIN_NFT_ADDRESS, protocolOwner);

Expand Down Expand Up @@ -67,19 +70,24 @@ FlightProduct = await ethers.getContractFactory("FlightProduct", {
ObjectTypeLib: process.env.OBJECTTYPELIB_ADDRESS,
ReferralLib: process.env.REFERRALLIB_ADDRESS,
SecondsLib: process.env.SECONDSLIB_ADDRESS,
StrLib: process.env.STRLIB_ADDRESS,
TimestampLib: process.env.TIMESTAMPLIB_ADDRESS,
VersionLib: process.env.VERSIONLIB_ADDRESS,
},
})
FlightProduct = FlightProduct.connect(flightOwner)
flightProduct = await FlightProduct.attach(process.env.FLIGHT_PRODUCT_ADDRESS)

// obtain bundle nft id from bundle creation tx logs
await flightProduct.setDefaultBundle('...')

// grant statistics data provider role to
await instance.grantRole(1000001, '...')
applicationSigner = '...'
await instance.grantRole(1000001, applicationSigner)

// grant status provider role to
await instance.grantRole(1000002, '...')
oracleSigner = '...'
await instance.grantRole(1000002, oracleSigner)

await flightProduct.setTestMode(true)

Expand Down
17 changes: 17 additions & 0 deletions hardhat.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,10 +53,19 @@ const config: HardhatUserConfig = {
count: 20,
},
},
base: {
chainId: 8453,
url: process.env.NETWORK_URL || "https://mainnet.base.org",
accounts: {
mnemonic: process.env.WALLET_MNEMONIC,
count: 20,
},
},
},
etherscan: {
apiKey: {
polygonAmoy: process.env.POLYGONSCAN_API_KEY || "",
base: process.env.BASESCAN_API_KEY || "",
},
customChains: [
{
Expand All @@ -66,6 +75,14 @@ const config: HardhatUserConfig = {
apiURL: "https://api-amoy.polygonscan.com/api",
browserURL: "https://amoy.polygonscan.com"
},
},
{
network: "base",
chainId: 8453,
urls: {
apiURL: "https://api.basescan.org/api",
browserURL: "https://basescan.org/"
},
}
]
},
Expand Down
Loading

0 comments on commit 75399e4

Please sign in to comment.