Skip to content

PayPledge Smart Contract ​

Overview ​

The PayPledge smart contract is the core component of the paypledge platform, deployed on a private EVM network. It manages a collateral-backed payment pledge from a buyer (payer) to a seller (payee), using Trade Tokens (ERC-3643) as collateral, represented as ERC-1155 tokens while under lock. The contract oversees the payment pledge lifecycle, including collateral deposit, condition fulfillment, seller acceptance, and settlement (repayment or default), with a refutation and dispute resolution mechanism.

This contract interacts with:

  • Buyer (payer), who initializes and discharges the pledge.
  • Seller (payee), who accepts the pledge and delivers goods.
  • Underwriters, who deposit collateral via the CollateralManager contract.
  • Dispute Resolve, who resolve disputes.
  • Payment Processor, who exchanges ERC-1155 tokens for early fiat financing.
  • CollateralManager contract, which transfers collateral.
  • Trade Token (ERC-3643), used as collateral.

Key Functionalities ​

1. Pledge Lifecycle Management ​

  • Manages the lifecycle: DRAFTING, INITIATED, ACCEPTED, CONTINGENT, EFFECTIVE, DISCHARGING, DISCHARGED.
  • Tracks discharge status: OPEN, DISCHARGE_INITIATED, DISCHARGE_REFUTED, DISCHARGED.
  • Transitions occur based on actions like initiation, acceptance, condition fulfillment, and discharge.

2. Collateral Management ​

  • Receives Trade Tokens (ERC-3643) as collateral from the CollateralManager contract via the depositCollateral function (in addition to the standard deposit function).
  • Only the CollateralManager contract can call depositCollateral, ensuring that collateral is only deposited as a result of a validated underwriting process.
  • Mints ERC-1155 tokens (token proxy) to represent the collateral, held by the seller or Payment Processor.
  • Transfers and burns of ERC-1155 tokens during discharge (repayment or default) using withdraw.
  • CollateralManager-driven flows ensure that only selected underwriter offers (CUOfs) result in collateral being locked in the PayPledge contract.
  • The contract stores the address of the CollateralManager and restricts certain functions to only be callable by this address.

3. Conditions and Refutations ​

  • Supports conditions (e.g., trade conditions for goods delivery) with statuses: NULL, UNFULFILLED, FULFILLMENT_INITIATED, FULFILLMENT_REFUTED, FULFILLED.
  • Allows refutations within a refutationWindow (e.g., 1 day) for condition fulfillment and discharge, resolved by the Dispute Resolver.

4. Seller Acceptance and Delivery ​

  • Enables the seller to accept the pledge (accept) and fulfill delivery conditions (fulfillCondition), moving the status to EFFECTIVE.

5. Compatability With Token Exchange for Early Financing ​

  • Allows the beneficiary to use their erc-1155 tokens in external trade contracts like the Token Exchange.

6. Discharge (Repayment or Default) ​

  • Repayment: Buyer initiates discharge (initiateDischarge), returning collateral (ERC-1155 tokens) to the underwriter after the refutation window.
  • Default: Payment Processor initiates initiateDefaultDischarge, claiming the collateral after the due date (60 days).
  • Handles refutations and dispute resolution with the help of the Dispute Resolver.

7. Change Requests ​

  • Allows the seller to request changes to the collateral value or due date (±5% range for collateral value).

Roles ​

  • Buyer (payer):
    • Initializes the pledge and initiates discharge on repayment.
    • Address: Immutable, set during deployment.
  • Seller (payee):
    • Accepts the pledge, fulfills delivery conditions, and initiates token exchange.
  • Underwriter:
    • Provides collateral via the CollateralManager contract.
  • DisputeResolver:
    • Resolves disputes.
    • Address: Set during initiation.

Events ​

  • StatusUpdated(PledgeStatus newStatus):
    • Emitted when the pledge status changes.
  • DischargeStatusUpdated(DischargeStatus newValue):
    • Emitted when the discharge status changes.
  • PaymentValueUpdated(uint256 oldValue, uint256 newValue):
    • Emitted when the collateral value is updated.
  • DueDateUpdated(uint256 oldValue, uint256 newValue):
    • Emitted when the due date is updated.
  • TokensDeposited(address indexed depositor, address indexed token, uint256 value, uint256 tokenId):
    • Emitted when collateral is deposited.
  • TokensWithdrawn(address indexed from, address indexed token, uint256 value, address indexed to):
    • Emitted when collateral is withdrawn.
  • ConditionAdded(uint256 conditionId, address indexed fulfiller):
    • Emitted when a condition is added.
  • ConditionFulfillmentInitiated(address fulfiller, uint256 conditionId):
    • Emitted when condition fulfillment is initiated.
  • ConditionFulfilled(uint256 conditionId):
    • Emitted when a condition is fulfilled.
  • ConditionFulfillmentRefuted(address refuter, uint256 conditionId):
    • Emitted when a condition fulfillment is refuted.
  • ConditionFulfillmentCancelled(address sender, uint256 conditionId):
    • Emitted when a condition fulfillment is cancelled.
  • DischargeInitiated():
    • Emitted when discharge (repayment or default) is initiated.
  • DischargeRefuted(address refuter):
    • Emitted when discharge is refuted.
  • DischargeCancelled():
    • Emitted when discharge is cancelled.
  • DischargeCompleted():
    • Emitted when discharge is completed.
  • CollateralDeposited(address indexed underwriter, address indexed token, uint256 value, address indexed to):
    • Emitted when the CollateralManager deposits collateral on behalf of an underwriter via depositCollateral.
  • underwriterPermissionUpdates(address underwriter, bool permission):
    • Emitted when underwriter permissions are updated by the paypledge owner.

Contract Structure ​

State Variables ​

  • string public name: Contract name.
  • uint256 public decimals: Token decimals.
  • string public referenceId: An arbitrary reference ID, set by the initiator for identifying the pay pledge.
  • address public immutable PAYER: The buyer address (immutable).
  • address public payee: The seller address.
  • address public disputeResolver: The Dispute Resolver's address.
  • address public collateralToken: The Trade Token (ERC-3643) address.
  • address public collateralManager: The CollateralManager contract address.
  • address public collateralDepositor: The account address that deposited the collateral for this pay pledge.
  • uint256 public collateralDeposited: The amount of collateral tokens deposited by collateral depositor.
  • uint256 public paymentValue: The value of collateral used in the pay pledge.
  • uint256 public pledgeDate: The timestamp when the pledge was made.
  • uint256 public dueDate: The due date for repayment (e.g., 60 days).
  • uint256 public refutationWindow: The time window (in seconds) for refutations.
  • mapping(address => bool) public whitelistedUnderwriters: The addresses whitelisted to participate in the underwriting for this pay pledge.
  • enum PledgeStatus { DRAFTING, INITIATED, ACCEPTED, CONTINGENT, EFFECTIVE, DISCHARGING, DISCHARGED }: Pledge lifecycle status.
  • enum DischargeStatus { OPEN, DISCHARGE_INITIATED, DEFAULT_DISCHARGE_INITIATED, DISCHARGE_REFUTED, DISCHARGED }: Discharge process status.
  • enum ConditionStatus { NULL, UNFULFILLED, FULFILLMENT_INITIATED, FULFILLMENT_REFUTED, FULFILLED }: Condition status.
  • enum ChangeTypes { COLLATERAL_VALUE, DUE_DATE }: Change types.
  • enum ConditionActions { NULL, DEPOSIT, COLLATERAL_DEPOSIT, ACCEPT, FULFILL_CONDITION, DISCHARGE }: Condition actions.
  • enum ConditionRequiredFields { TRADE_TOKEN_ADDRESS, TRADE_TOKEN_VALUE }: Condition required fields.
  • enum ConditionFulfillmentActions { SET_VALUE }: Condition fulfillment actions.
  • enum ConditionFulfillmentFields { STATUS, DISCHARGE_STATUS, TRANSFER_FROM, TRANSFER_TO, TRANSFER_VALUE, TRANSFER_TOKEN_ID }: Condition fulfillment fields.
  • PledgeStatus public status: Current pledge status.
  • DischargeStatus public dischargeStatus: Current discharge status.
  • struct Condition { enum ConditionActions action; struct FieldRequirement[] requiredFields; address fulfiller; enum ConditionStatus status; enum ConditionFulfillmentActions fulfillmentAction; struct FieldUpdate[] fulfillmentFields; uint256 fulfillmentRequestTimestamp; }: Structure to store condition details.
  • struct NewCondition { uint256 conditionId; enum ConditionActions triggeringAction; enum ConditionRequiredFields[] requiredFields; bytes[] requiredValues; address fulfiller; enum ConditionFulfillmentActions fulfillmentAction; enum ConditionFulfillmentFields[] fulfillmentFields; bytes[] fulfillmentValues; }: Structure for new conditions.
  • struct FieldRequirement { enum ConditionRequiredFields field; bytes value; }: Structure for field requirements.
  • struct FieldUpdate { enum ConditionFulfillmentFields field; bytes value; }: Structure for field updates.
  • mapping(uint256 => Condition) public conditions: Mapping of condition IDs to conditions.
  • uint256[] public conditionIds: Array of condition IDs.
  • address[] public dischargeAccounts: Accounts to be drained on discharge.
  • uint256[] public dischargeValues: Values to be drained on discharge.
  • address public dischargeToken: Token to be drained on discharge.

Functions ​

Constructor ​

  • constructor(address _initialOwner, address _payer, string memory _erc1155Uri):
    • Initializes the contract with the owner, payer, and ERC-1155 URI.
    • Sets the contract status to "DRAFTING" and discharge status to "OPEN".

Admin Functions ​

  • whitelistUnderwriter(address underwriter, bool permission):
    • Allows the contract owner to add or remove underwriters from the whitelist.
    • Only whitelisted underwriters can participate in the underwriting process.
    • Emits underwriterPermissionUpdates.

Buyer Functions ​

  • initiate(string memory _referenceId, address _payee, address _collateralToken, uint256 _paymentValue, uint256 _pledgeDate, uint256 _dueDate, uint256 _refutationWindow, address _disputeResolver, NewCondition[] memory _newConditions):
    • Initiates the pledge with the specified details and conditions.
    • Only callable by the contract deployer.
    • Emits StatusUpdated.
  • addCondition(uint256 _conditionId, ConditionActions _triggeringAction, ConditionRequiredFields[] memory _requiredFields, bytes[] memory _requiredValues, address _fulfiller, ConditionFulfillmentActions _fulfillmentAction, ConditionFulfillmentFields[] memory _fulfillmentFields, bytes[] memory _fulfillmentValues):
    • Adds a new condition to the pledge.
    • Only callable by the paypledge owner(payer).
    • Emits ConditionAdded.
  • initiateDischarge(address[] calldata accounts):
    • Initiates discharge on repayment, specifying accounts to receive collateral.
    • Only callable by the payer.
    • Emits DischargeInitiated, StatusUpdated.
  • completeDischarge():
    • Completes discharge after the refutation window, transferring collateral back to the underwriter.
    • Callable by the payer or Dispute Resolver (if refuted).
    • Emits DischargeCompleted, StatusUpdated.

Seller Functions ​

  • accept():
    • Accepts the pledge, moving status to ACCEPTED.
    • Only callable by the payee.
    • Emits StatusUpdated.
  • fulfillCondition(uint256 conditionId):
    • Fulfills a condition (e.g., delivery), moving status to EFFECTIVE if applicable.
    • Only callable by the condition’s fulfiller (e.g., payee).
    • Emits ConditionFulfilled, StatusUpdated.
  • initiateConditionFulfillment(uint256 conditionId):
    • Initiates condition fulfillment, starting the refutation window.
    • Only callable by the condition’s fulfiller.
    • Emits ConditionFulfillmentInitiated.
  • completeConditionFulfillment(uint256 conditionId):
    • Completes condition fulfillment after the refutation window.
    • Callable by the fulfiller or Dispute Resolver (if refuted).
    • Emits ConditionFulfilled, StatusUpdated.
  • requestChange(ChangeTypes _changeType, bytes memory newValue):
    • Requests a change to the collateral value or due date.
    • Only callable by the payee.
    • Emits PaymentValueUpdated or DueDateUpdated.

Collateral Beneficiary Functions(seller/payment processor) ​

  • initiateDefaultDischarge(address[] calldata accounts):
    • Initiates discharge on default, claiming the collateral after the due date.
    • Only callable by accounts with a collateral balance(e.g.: Payment Processor).
    • Emits DischargeInitiated, StatusUpdated.
  • completeDefaultDischarge():
    • Completes the default discharge process after the refutation window has passed.
    • Callable by collateral owner or dispute resolver.
    • Emits DischargeCompleted, StatusUpdated.

Refutation Functions ​

  • refuteConditionFulfillment(uint256 conditionId):
    • Refutes a condition fulfillment within the refutation window.
    • Callable by the payer or payee.
    • Emits ConditionFulfillmentRefuted.
  • cancelConditionFulfillment(uint256 conditionId):
    • Cancels a condition fulfillment if refuted.
    • Callable by the Dispute Resolver or fulfiller.
    • Emits ConditionFulfillmentCancelled.
  • refuteDischarge():
    • Refutes a discharge within the refutation window.
    • Callable by collateral holders (e.g., Seller or Payment Processor).
    • Emits DischargeRefuted.
  • cancelDischarge():
    • Cancels a discharge if refuted.
    • Only callable by the Dispute Resolver.
    • Emits DischargeCancelled, StatusUpdated.

Collateral Functions ​

  • depositCollateral(uint256 _value):
    • Allows whitelisted underwriters to deposit collateral tokens that back the pledge.
    • Only callable by whitelisted underwriters.
    • Emits TokensDeposited.
  • deposit(address _token, uint256 _value, address _to):
    • Deposits Trade Tokens, minting ERC-1155 tokens.
    • Fulfills deposit conditions if applicable.
    • Emits TokensDeposited, StatusUpdated.
  • withdraw(address _token, uint256 _value, address _to):
    • Withdraws Trade Tokens, burning ERC-1155 tokens.
    • Restricted until after the due date or DISCHARGED status.
    • Emits TokensWithdrawn.

ERC-1155 Functions ​

  • safeTransferFrom(address from, address to, uint256 id, uint256 value, bytes data):
    • Safely transfers ERC-1155 tokens with custom collateral restrictions.
    • Only internal transfers are used in the current implementation.
  • safeBatchTransferFrom(address from, address to, uint256[] ids, uint256[] values, bytes data):
    • Safely transfers a batch of ERC-1155 tokens with custom collateral restrictions.
    • Only internal transfers are used in the current implementation.
  • onERC1155Received(address, address, uint256, uint256, bytes) external pure returns (bytes4):
    • Handles the receipt of a single ERC-1155 token transfer.
    • Required for ERC1155 compliance.
  • onERC1155BatchReceived(address, address, uint256[], uint256[], bytes) external pure returns (bytes4):
    • Handles the receipt of a batch of ERC-1155 token transfers.
    • Required for ERC1155 compliance.

Internal Functions ​

  • _verifyCondition(uint256 _conditionId, address _token, uint256 _value) internal view returns (bool):
    • Verifies if a condition is met based on the provided token and value.
  • _fulfillCondition(uint256 _conditionId) internal:
    • Internal function to fulfill a condition and execute its associated actions.
  • _isCompatibleERC20(address token) internal returns (bool, string):
    • Checks if the specified address is a valid ERC20 token.
  • _deleteCondition(uint256 _conditionId) internal:
    • Deletes the specified condition and removes it from the conditionIds array.
  • _isDischargeAccount(address _account) internal view returns (bool):
    • Checks if the specified address is a discharge account.

View Functions ​

  • getStatus() external view returns (PledgeStatus):
    • Returns the current pledge status.
  • getConditionCount() public view returns (uint256):
    • Returns the total number of conditions.
  • getAllConditionIds() public view returns (uint256[] memory):
    • Returns an array of all condition IDs.

Errors ​

  • PayPledgeInvalidAddress(address receivedAddress):
    • Thrown when an invalid address is received.
  • PayPledgeConditionAlreadyExists(uint256 conditionId):
    • Thrown when a condition with the specified ID already exists.
  • PayPledgeInvalidConditionStatus(enum ConditionStatus conditionStatus):
    • Thrown when the status of a condition is invalid.
  • PayPledgeTransferFailed(address token, address to, uint256 value):
    • Thrown when an ERC-20 token transfer fails.
  • PayPledgeInvalidStatus(enum PledgeStatus status):
    • Thrown when the deposit state is invalid.
  • PayPledgeUnauthorizedCaller(address sender):
    • Thrown when an unauthorized caller attempts to interact with the contract.
  • PayPledgeInvalidConditionId(uint256 conditionId):
    • Thrown when an invalid condition ID is provided.
  • PayPledgeInvalidDischargeStatus(enum DischargeStatus dischargeStatus):
    • Thrown when the discharge status is invalid.
  • PayPledgeUnauthorizedCollateralWithdrawal(uint256 dueDateTill, enum PledgeStatus status):
    • Thrown when an unauthorized attempt is made to withdraw collateral.
  • PayPledgeDueDateNotPassed(uint256 currentTime, uint256 dueDate):
    • Thrown when an action is attempted before the due date has passed.
  • PayPledgeActiveRefutationWindow(uint256 currentTime, uint256 refutationWindowTill):
    • Thrown when a refutation window is still active for a pay pledge.
  • PayPledgeInvalidDischargeTimestamp(uint256 currentTime, uint256 dueDate):
    • Thrown when a default discharge request is sent before due date.
  • PayPledgeUnauthorizedResolver(address sender, address disputeResolver):
    • Thrown when an unauthorized resolver attempts to resolve a dispute.
  • PayPledgeUnauthorizedCollateralTransfer():
    • Thrown when an unauthorized attempt is made to transfer collateral.
  • PayPledgeInvalidValueChange(uint256 current, uint256 newValue, uint256 lowerBound, uint256 upperBound):
    • Thrown when a value change is outside the allowed range.
  • ERC1155MissingApprovalForAll(address operator, address owner):
    • Thrown when there's a failure with the operator's approval.
  • PayPledgeInvalidData():
    • Thrown when invalid data is provided.

Security Considerations ​

  • Access Control:
    • Role-based restrictions ensure only authorized parties (payer, payee, Payment Processor) can call specific functions.
  • Collateral Safety:
    • ERC-1155 tokens are minted and transferred securely, ensuring collateral integrity.
    • Trade Tokens are only released after proper discharge or due date expiration.
  • Reentrancy Protection:
    • Functions that modify state (e.g., deposit, withdraw, initiateDischarge) use reentrancy guards to prevent reentrancy attacks.
  • Refutation Window:
    • The refutationWindow ensures parties have time to dispute actions, with the Dispute Resolver as the final arbiter.

Dependencies ​

  • OpenZeppelin Contracts:
    • Ownable: For access control (Dispute Resolver).
    • ReentrancyGuard: For reentrancy protection.
    • ERC1155: For managing token proxies (collateral representation).
    • IERC20: For interacting with Trade Tokens (ERC-3643).
  • External Contracts:
    • TradeToken (ERC-3643): The collateral token.
    • CollateralManager Contract: Transfers collateral to the PayPledge.

Deployment ​

  • Network: Private EVM network (custom Ethereum fork).
  • Parameters:
    • _initialOwner: Address of the Dispute Resolver.
    • _payer: Address of the buyer (payer).
    • _erc1155Uri: URI for the ERC-1155 token metadata.