pledge.sol

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);
    }
}

Last updated