Skip to content

Instantly share code, notes, and snippets.

@andrewgcodes
Created February 16, 2025 01:32
Show Gist options
  • Save andrewgcodes/b987c700851e1ef6a9bc36752c447726 to your computer and use it in GitHub Desktop.
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=
// 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