Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TRST audit fixes for Graph Payments contracts #1072

Merged
merged 10 commits into from
Dec 17, 2024
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
Loading