Created
February 16, 2025 01:32
-
-
Save andrewgcodes/b987c700851e1ef6a9bc36752c447726 to your computer and use it in GitHub Desktop.
Created using remix-ide: Realtime Ethereum Contract Compiler and Runtime. Load this file by pasting this gists URL or ID at https://remix.ethereum.org/#version=soljson-v0.8.26+commit.8a97fa7a.js&optimize=false&runs=200&gist=
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// SPDX-License-Identifier: MIT | |
// USE AT OWN RISK, MADE FOR HACKATHON BY BEGINNER!!!! | |
pragma solidity ^0.8.0; | |
contract DisasterPropertyInsurance { | |
enum Tier { Bronze, Silver, Gold } | |
uint256 public constant POLICY_DURATION = 2 minutes; | |
uint256 public constant WAITING_PERIOD = 5 seconds; | |
uint256 public constant PREMIUM_INTERVAL = 30 seconds; | |
uint256 public constant VOTING_PERIOD = 120 seconds; | |
uint256 public constant MAX_CLAIMS = 3; | |
uint256 public constant PREMIUM_BRONZE = 1e12; | |
uint256 public constant PREMIUM_SILVER = 2e12; | |
uint256 public constant PREMIUM_GOLD = 3e12; | |
uint256 public constant PAYOUT_BRONZE = 5e12; | |
uint256 public constant PAYOUT_SILVER = 7e12; | |
uint256 public constant PAYOUT_GOLD = 10e12; | |
uint256 public constant DEDUCTIBLE_BRONZE = 1e12; | |
uint256 public constant DEDUCTIBLE_SILVER = 1e12; | |
uint256 public constant DEDUCTIBLE_GOLD = 1e12; | |
struct Policy { | |
bool active; | |
uint256 expiration; | |
uint256 coverageStart; | |
Tier tier; | |
uint256 nextPaymentDue; | |
uint256 totalPayoutReceived; | |
uint256 claimsFiled; | |
bool blacklisted; | |
} | |
mapping(address => Policy) public policies; | |
struct Claim { | |
address claimant; | |
uint256 yesVotes; | |
uint256 noVotes; | |
uint256 voteDeadline; | |
bool finalized; | |
bool approved; | |
string evidence; | |
mapping(address => bool) voted; | |
} | |
uint256 public claimCounter; | |
mapping(uint256 => Claim) private claims; | |
event PolicyBought(address indexed buyer, Tier tier, uint256 expiration); | |
event PolicyRenewed(address indexed policyHolder, uint256 newExpiration); | |
event ClaimFiled(uint256 indexed claimId, address indexed claimant, uint256 voteDeadline, string evidence); | |
event Voted(uint256 indexed claimId, address indexed voter, bool support, uint256 voteWeight); | |
event ClaimFinalized(uint256 indexed claimId, bool approved, uint256 payout); | |
modifier onlyActivePolicy() { | |
require(policies[msg.sender].active, "No active policy"); | |
_; | |
} | |
function getPremium(Tier tier) public pure returns (uint256) { | |
if (tier == Tier.Bronze) return PREMIUM_BRONZE; | |
if (tier == Tier.Silver) return PREMIUM_SILVER; | |
if (tier == Tier.Gold) return PREMIUM_GOLD; | |
revert("Invalid tier"); | |
} | |
function getPayout(Tier tier) public pure returns (uint256) { | |
if (tier == Tier.Bronze) return PAYOUT_BRONZE; | |
if (tier == Tier.Silver) return PAYOUT_SILVER; | |
if (tier == Tier.Gold) return PAYOUT_GOLD; | |
revert("Invalid tier"); | |
} | |
function getDeductible(Tier tier) public pure returns (uint256) { | |
if (tier == Tier.Bronze) return DEDUCTIBLE_BRONZE; | |
if (tier == Tier.Silver) return DEDUCTIBLE_SILVER; | |
if (tier == Tier.Gold) return DEDUCTIBLE_GOLD; | |
revert("Invalid tier"); | |
} | |
function getVoteWeight(address voter) public view returns (uint256) { | |
Policy storage p = policies[voter]; | |
if (!p.active) return 0; | |
if (p.tier == Tier.Gold) return 3; | |
if (p.tier == Tier.Silver) return 2; | |
return 1; | |
} | |
function getRiskScore(address) public pure returns (uint256) { | |
return 5; | |
} | |
function buyPolicy(Tier tier) external payable { | |
Policy storage p = policies[msg.sender]; | |
require(!p.active || block.timestamp >= p.expiration, "Active policy exists"); | |
require(!p.blacklisted, "Address blacklisted"); | |
uint256 requiredPremium = getPremium(tier); | |
require(msg.value == requiredPremium, "Incorrect premium amount"); | |
p.active = true; | |
p.tier = tier; | |
p.expiration = block.timestamp + POLICY_DURATION; | |
p.coverageStart = block.timestamp + WAITING_PERIOD; | |
p.nextPaymentDue = block.timestamp + PREMIUM_INTERVAL; | |
p.totalPayoutReceived = 0; | |
p.claimsFiled = 0; | |
p.blacklisted = false; | |
emit PolicyBought(msg.sender, tier, p.expiration); | |
} | |
function renewPolicy() external payable onlyActivePolicy { | |
Policy storage p = policies[msg.sender]; | |
require(!p.blacklisted, "Policy blacklisted"); | |
require(block.timestamp >= p.nextPaymentDue, "Too early to renew"); | |
uint256 requiredPremium = getPremium(p.tier); | |
require(msg.value == requiredPremium, "Incorrect premium amount for renewal"); | |
p.expiration = block.timestamp + POLICY_DURATION; | |
p.nextPaymentDue = block.timestamp + PREMIUM_INTERVAL; | |
emit PolicyRenewed(msg.sender, p.expiration); | |
} | |
function fileClaim(string calldata evidence) external onlyActivePolicy { | |
Policy storage p = policies[msg.sender]; | |
require(block.timestamp >= p.coverageStart, "Coverage not active yet"); | |
require(block.timestamp < p.expiration, "Policy expired"); | |
require(p.claimsFiled < MAX_CLAIMS, "Maximum claims filed"); | |
claimCounter++; | |
Claim storage c = claims[claimCounter]; | |
c.claimant = msg.sender; | |
c.voteDeadline = block.timestamp + VOTING_PERIOD; | |
c.evidence = evidence; | |
p.claimsFiled += 1; | |
emit ClaimFiled(claimCounter, msg.sender, c.voteDeadline, evidence); | |
} | |
function voteOnClaim(uint256 claimId, bool support) external onlyActivePolicy { | |
Claim storage c = claims[claimId]; | |
require(block.timestamp < c.voteDeadline, "Voting period ended"); | |
require(!c.voted[msg.sender], "Already voted on this claim"); | |
uint256 weight = getVoteWeight(msg.sender); | |
c.voted[msg.sender] = true; | |
if (support) { | |
c.yesVotes += weight; | |
} else { | |
c.noVotes += weight; | |
} | |
emit Voted(claimId, msg.sender, support, weight); | |
} | |
function finalizeClaim(uint256 claimId) external { | |
Claim storage c = claims[claimId]; | |
require(block.timestamp >= c.voteDeadline, "Voting period not ended"); | |
require(!c.finalized, "Claim already finalized"); | |
c.finalized = true; | |
uint256 payout = 0; | |
if (c.yesVotes > c.noVotes) { | |
Policy storage p = policies[c.claimant]; | |
if (p.active && block.timestamp < p.expiration && !p.blacklisted) { | |
uint256 grossPayout = getPayout(p.tier); | |
uint256 deductible = getDeductible(p.tier); | |
if (grossPayout > deductible) { | |
payout = grossPayout - deductible; | |
} | |
require(address(this).balance >= payout, "Insufficient funds in pool"); | |
p.totalPayoutReceived += payout; | |
payable(c.claimant).transfer(payout); | |
c.approved = true; | |
} else { | |
c.approved = false; | |
} | |
} else { | |
c.approved = false; | |
policies[c.claimant].blacklisted = true; | |
policies[c.claimant].active = false; | |
} | |
emit ClaimFinalized(claimId, c.approved, payout); | |
} | |
function getClaim(uint256 claimId) | |
external | |
view | |
returns ( | |
address claimant, | |
uint256 yesVotes, | |
uint256 noVotes, | |
uint256 voteDeadline, | |
bool finalized, | |
bool approved, | |
string memory evidence | |
) | |
{ | |
Claim storage c = claims[claimId]; | |
return ( | |
c.claimant, | |
c.yesVotes, | |
c.noVotes, | |
c.voteDeadline, | |
c.finalized, | |
c.approved, | |
c.evidence | |
); | |
} | |
function getPolicy(address user) | |
external | |
view | |
returns ( | |
bool active, | |
uint256 expiration, | |
uint256 coverageStart, | |
Tier tier, | |
uint256 nextPaymentDue, | |
uint256 totalPayoutReceived, | |
uint256 claimsFiled, | |
bool blacklisted | |
) | |
{ | |
Policy storage p = policies[user]; | |
return ( | |
p.active, | |
p.expiration, | |
p.coverageStart, | |
p.tier, | |
p.nextPaymentDue, | |
p.totalPayoutReceived, | |
p.claimsFiled, | |
p.blacklisted | |
); | |
} | |
receive() external payable {} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment