The PortexPledge contract facilitates the creation and management of Pledges onchain, holding funds in a non-custodial escrow, and determining their distribution based on the verification by an oracle.
Contract Functions
verifyPledge()
Can only be called by the oracle.
Verifies the pledge after the expiration block (pledge deadline) but within 5000 blocks post-expiration.
Transfers the contract's ether balance (after deducting the oracle fee) to the deployer if the result of the pledge is true, or to the beneficiary if false.
Pays the oracle fee and emits PledgeVerified and FundsWithdrawn events.
withdraw()
Can only be called by the contract deployer.
Allows the deployer to withdraw funds if the verification period has expired without verification.
Emits a FundsWithdrawn event.
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract PortexPledge {
address public immutable deployer;
address public immutable beneficiary;
address public immutable oracle;
uint256 public immutable expirationBlock;
string public appId;
uint256 public constant ORACLE_FEE = 1000000; // in Wei
bool public verified;
bool public result;
event PledgeCreated(address indexed deployer, address indexed beneficiary, address indexed oracle, uint256 expirationBlock, string appId);
event PledgeVerified(bool result, address indexed oracle);
event FundsWithdrawn(address indexed recipient, uint256 amount);
constructor(uint256 _expirationBlock, address _beneficiary, address _oracle, string memory _appId) payable {
require(msg.value >= ORACLE_FEE, "Insufficient funds to cover oracle fee");
deployer = msg.sender;
beneficiary = _beneficiary;
oracle = _oracle;
expirationBlock = _expirationBlock;
appId = _appId;
emit PledgeCreated(deployer, beneficiary, oracle, expirationBlock, appId);
}
modifier onlyOracle() {
require(msg.sender == oracle, "Only oracle can call this function");
_;
}
modifier onlyDeployer() {
require(msg.sender == deployer, "Only the deployer can call this function");
_;
}
function verifyPledge(bool _result) external onlyOracle {
require(block.number >= expirationBlock, "Pledge has not expired yet");
require(block.number <= expirationBlock + 5000, "Verification period has expired");
require(!verified, "Pledge already verified");
verified = true;
result = _result;
uint256 balance = address(this).balance - ORACLE_FEE;
address recipient = _result ? deployer : beneficiary;
payable(recipient).transfer(balance);
emit FundsWithdrawn(recipient, balance);
payable(oracle).transfer(ORACLE_FEE);
emit PledgeVerified(_result, oracle);
}
function withdraw() external onlyDeployer {
require(block.number > expirationBlock + 5000, "Cannot withdraw before verification period ends");
require(!verified, "Pledge already verified");
uint256 balance = address(this).balance;
payable(deployer).transfer(balance);
emit FundsWithdrawn(deployer, balance);
}
}