Skip to content

Commit

Permalink
Merge pull request #1072 from graphprotocol/tmigone/trust-fixes-payments
Browse files Browse the repository at this point in the history
  • Loading branch information
tmigone authored Dec 17, 2024
2 parents 032e4a4 + 0542ab7 commit 1109537
Show file tree
Hide file tree
Showing 29 changed files with 897 additions and 698 deletions.
35 changes: 22 additions & 13 deletions packages/horizon/contracts/interfaces/IGraphPayments.sol
Original file line number Diff line number Diff line change
Expand Up @@ -23,48 +23,57 @@ interface IGraphPayments {
* @param payer The address of the payer
* @param receiver The address of the receiver
* @param dataService The address of the data service
* @param tokensReceiver Amount of tokens for the receiver
* @param tokensDelegationPool Amount of tokens for delegators
* @param tokensDataService Amount of tokens for the data service
* @param tokens The total amount of tokens being collected
* @param tokensProtocol Amount of tokens charged as protocol tax
* @param tokensDataService Amount of tokens for the data service
* @param tokensDelegationPool Amount of tokens for delegators
* @param tokensReceiver Amount of tokens for the receiver
*/
event PaymentCollected(
event GraphPaymentCollected(
address indexed payer,
address indexed receiver,
address indexed dataService,
uint256 tokensReceiver,
uint256 tokensDelegationPool,
uint256 tokens,
uint256 tokensProtocol,
uint256 tokensDataService,
uint256 tokensProtocol
uint256 tokensDelegationPool,
uint256 tokensReceiver
);

/**
* @notice Thrown when there are insufficient tokens to pay the required amount
* @param tokens The amount of tokens available
* @param minTokens The amount of tokens being collected
* @notice Thrown when the calculated amount of tokens to be paid out to all parties is
* not the same as the amount of tokens being collected
* @param tokens The amount of tokens being collected
* @param tokensCalculated The sum of all the tokens to be paid out
*/
error GraphPaymentsInsufficientTokens(uint256 tokens, uint256 minTokens);
error GraphPaymentsBadAccounting(uint256 tokens, uint256 tokensCalculated);

/**
* @notice Thrown when the protocol payment cut is invalid
* @param protocolPaymentCut The protocol payment cut
*/
error GraphPaymentsInvalidProtocolPaymentCut(uint256 protocolPaymentCut);

/**
* @notice Thrown when trying to use a cut that is not expressed in PPM
* @param cut The cut
*/
error GraphPaymentsInvalidCut(uint256 cut);

/**
* @notice Collects funds from a payer.
* It will pay cuts to all relevant parties and forward the rest to the receiver.
* @param paymentType The type of payment as defined in {IGraphPayments}
* @param receiver The address of the receiver
* @param tokens The amount of tokens being collected
* @param dataService The address of the data service
* @param tokensDataService The amount of tokens that should be sent to the data service
* @param dataServiceCut The data service cut in PPM
*/
function collect(
PaymentTypes paymentType,
address receiver,
uint256 tokens,
address dataService,
uint256 tokensDataService
uint256 dataServiceCut
) external;
}
6 changes: 2 additions & 4 deletions packages/horizon/contracts/interfaces/IPaymentsCollector.sol
Original file line number Diff line number Diff line change
Expand Up @@ -19,17 +19,15 @@ interface IPaymentsCollector {
* @param paymentType The payment type collected as defined by {IGraphPayments}
* @param payer The address of the payer
* @param receiver The address of the receiver
* @param tokensReceiver The amount of tokens received by the receiver
* @param dataService The address of the data service
* @param tokensDataService The amount of tokens received by the data service
* @param tokens The amount of tokens being collected
*/
event PaymentCollected(
IGraphPayments.PaymentTypes indexed paymentType,
address indexed payer,
address receiver,
uint256 tokensReceiver,
address indexed dataService,
uint256 tokensDataService
uint256 tokens
);

/**
Expand Down
106 changes: 3 additions & 103 deletions packages/horizon/contracts/interfaces/IPaymentsEscrow.sol
Original file line number Diff line number Diff line change
Expand Up @@ -25,50 +25,6 @@ interface IPaymentsEscrow {
uint256 thawEndTimestamp;
}

/// @notice Details for a payer-collector pair
/// @dev Collectors can be removed only after a thawing period
struct Collector {
// Amount of tokens the collector is allowed to collect
uint256 allowance;
// Timestamp at which the collector thawing period ends (zero if not thawing)
uint256 thawEndTimestamp;
}

/**
* @notice Emitted when a payer authorizes a collector to collect funds
* @param payer The address of the payer
* @param collector The address of the collector
* @param addedAllowance The amount of tokens added to the collector's allowance
* @param newTotalAllowance The new total allowance after addition
*/
event AuthorizedCollector(
address indexed payer,
address indexed collector,
uint256 addedAllowance,
uint256 newTotalAllowance
);

/**
* @notice Emitted when a payer thaws a collector
* @param payer The address of the payer
* @param collector The address of the collector
*/
event ThawCollector(address indexed payer, address indexed collector);

/**
* @notice Emitted when a payer cancels the thawing of a collector
* @param payer The address of the payer
* @param collector The address of the collector
*/
event CancelThawCollector(address indexed payer, address indexed collector);

/**
* @notice Emitted when a payer revokes a collector authorization.
* @param payer The address of the payer
* @param collector The address of the collector
*/
event RevokeCollector(address indexed payer, address indexed collector);

/**
* @notice Emitted when a payer deposits funds into the escrow for a payer-collector-receiver tuple
* @param payer The address of the payer
Expand Down Expand Up @@ -152,13 +108,6 @@ interface IPaymentsEscrow {
*/
error PaymentsEscrowThawingPeriodTooLong(uint256 thawingPeriod, uint256 maxWaitPeriod);

/**
* @notice Thrown when a collector has insufficient allowance to collect funds
* @param allowance The current allowance
* @param minAllowance The minimum required allowance
*/
error PaymentsEscrowInsufficientAllowance(uint256 allowance, uint256 minAllowance);

/**
* @notice Thrown when the contract balance is not consistent with the collection amount
* @param balanceBefore The balance before the collection
Expand All @@ -172,54 +121,6 @@ interface IPaymentsEscrow {
*/
error PaymentsEscrowInvalidZeroTokens();

/**
* @notice Authorize a collector to collect funds from the payer's escrow
* @dev This function can only be used to increase the allowance of a collector.
* To reduce it the authorization must be revoked and a new one must be created.
*
* Requirements:
* - `allowance` must be greater than zero
*
* Emits an {AuthorizedCollector} event
*
* @param collector The address of the collector
* @param allowance The amount of tokens to add to the collector's allowance
*/
function approveCollector(address collector, uint256 allowance) external;

/**
* @notice Thaw a collector's collector authorization
* @dev The thawing period is defined by the `REVOKE_COLLECTOR_THAWING_PERIOD` constant
*
* Emits a {ThawCollector} event
*
* @param collector The address of the collector
*/
function thawCollector(address collector) external;

/**
* @notice Cancel a collector's authorization thawing
* @dev Requirements:
* - `collector` must be thawing
*
* Emits a {CancelThawCollector} event
*
* @param collector The address of the collector
*/
function cancelThawCollector(address collector) external;

/**
* @notice Revoke a collector's authorization.
* Removes the collector from the list of authorized collectors.
* @dev Requirements:
* - `collector` must have thawed
*
* Emits a {RevokeCollector} event
*
* @param collector The address of the collector
*/
function revokeCollector(address collector) external;

/**
* @notice Deposits funds into the escrow for a payer-collector-receiver tuple, where
* the payer is the transaction caller.
Expand Down Expand Up @@ -277,8 +178,6 @@ interface IPaymentsEscrow {
* @notice Collects funds from the payer-collector-receiver's escrow and sends them to {GraphPayments} for
* distribution using the Graph Horizon Payments protocol.
* The function will revert if there are not enough funds in the escrow.
* @dev Requirements:
* - `collector` needs to be authorized by the payer and have enough allowance
*
* Emits an {EscrowCollected} event
*
Expand All @@ -287,19 +186,20 @@ interface IPaymentsEscrow {
* @param receiver The address of the receiver
* @param tokens The amount of tokens to collect
* @param dataService The address of the data service
* @param tokensDataService The amount of tokens that {GraphPayments} should send to the data service
* @param dataServiceCut The data service cut in PPM that {GraphPayments} should send
*/
function collect(
IGraphPayments.PaymentTypes paymentType,
address payer,
address receiver,
uint256 tokens,
address dataService,
uint256 tokensDataService
uint256 dataServiceCut
) external;

/**
* @notice Get the balance of a payer-collector-receiver tuple
* This function will return 0 if the current balance is less than the amount of funds being thawed.
* @param payer The address of the payer
* @param collector The address of the collector
* @param receiver The address of the receiver
Expand Down
58 changes: 57 additions & 1 deletion packages/horizon/contracts/interfaces/ITAPCollector.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
pragma solidity 0.8.27;

import { IPaymentsCollector } from "./IPaymentsCollector.sol";
import { IGraphPayments } from "./IGraphPayments.sol";

/**
* @title Interface for the {TAPCollector} contract
Expand All @@ -18,10 +19,14 @@ interface ITAPCollector is IPaymentsCollector {
address payer;
// Timestamp at which thawing period ends (zero if not thawing)
uint256 thawEndTimestamp;
// Whether the signer authorization was revoked
bool revoked;
}

/// @notice The Receipt Aggregate Voucher (RAV) struct
struct ReceiptAggregateVoucher {
// The address of the payer the RAV was issued by
address payer;
// The address of the data service the RAV was issued to
address dataService;
// The address of the service provider the RAV was issued to
Expand Down Expand Up @@ -119,6 +124,19 @@ interface ITAPCollector is IPaymentsCollector {
*/
error TAPCollectorSignerNotAuthorizedByPayer(address payer, address signer);

/**
* Thrown when the attempting to revoke a signer that was already revoked
* @param signer The address of the signer
*/
error TAPCollectorAuthorizationAlreadyRevoked(address payer, address signer);

/**
* Thrown when attempting to thaw a signer that is already thawing
* @param signer The address of the signer
* @param thawEndTimestamp The timestamp at which the thawing period ends
*/
error TAPCollectorSignerAlreadyThawing(address signer, uint256 thawEndTimestamp);

/**
* Thrown when the signer is not thawing
* @param signer The address of the signer
Expand All @@ -137,6 +155,19 @@ interface ITAPCollector is IPaymentsCollector {
*/
error TAPCollectorInvalidRAVSigner();

/**
* Thrown when the RAV payer does not match the signers authorized payer
* @param authorizedPayer The address of the authorized payer
* @param ravPayer The address of the RAV payer
*/
error TAPCollectorInvalidRAVPayer(address authorizedPayer, address ravPayer);

/**
* Thrown when the RAV is for a data service the service provider has no provision for
* @param dataService The address of the data service
*/
error TAPCollectorUnauthorizedDataService(address dataService);

/**
* Thrown when the caller is not the data service the RAV was issued to
* @param caller The address of the caller
Expand All @@ -153,7 +184,15 @@ interface ITAPCollector is IPaymentsCollector {
error TAPCollectorInconsistentRAVTokens(uint256 tokens, uint256 tokensCollected);

/**
* @notice Authorize a signer to sign on behalf of the payer
* Thrown when the attempting to collect more tokens than what it's owed
* @param tokensToCollect The amount of tokens to collect
* @param maxTokensToCollect The maximum amount of tokens to collect
*/
error TAPCollectorInvalidTokensToCollectAmount(uint256 tokensToCollect, uint256 maxTokensToCollect);

/**
* @notice Authorize a signer to sign on behalf of the payer.
* A signer can not be authorized for multiple payers even after revoking previous authorizations.
* @dev Requirements:
* - `signer` must not be already authorized
* - `proofDeadline` must be greater than the current timestamp
Expand Down Expand Up @@ -213,4 +252,21 @@ interface ITAPCollector is IPaymentsCollector {
* @return The hash of the RAV.
*/
function encodeRAV(ReceiptAggregateVoucher calldata rav) external view returns (bytes32);

/**
* @notice See {IPaymentsCollector.collect}
* This variant adds the ability to partially collect a RAV by specifying the amount of tokens to collect.
*
* Requirements:
* - The amount of tokens to collect must be less than or equal to the total amount of tokens in the RAV minus
* the tokens already collected.
* @param paymentType The payment type to collect
* @param data Additional data required for the payment collection
* @param tokensToCollect The amount of tokens to collect
*/
function collect(
IGraphPayments.PaymentTypes paymentType,
bytes calldata data,
uint256 tokensToCollect
) external returns (uint256);
}
Loading

0 comments on commit 1109537

Please sign in to comment.