Skip to content

Commit 65f4d68

Browse files
committed
fix: remove collector allowance feature from payments escrow (TRST-CL1)
Signed-off-by: Tomás Migone <[email protected]>
1 parent 9dc58d0 commit 65f4d68

File tree

16 files changed

+10
-384
lines changed

16 files changed

+10
-384
lines changed

packages/horizon/contracts/interfaces/IPaymentsEscrow.sol

Lines changed: 0 additions & 101 deletions
Original file line numberDiff line numberDiff line change
@@ -25,50 +25,6 @@ interface IPaymentsEscrow {
2525
uint256 thawEndTimestamp;
2626
}
2727

28-
/// @notice Details for a payer-collector pair
29-
/// @dev Collectors can be removed only after a thawing period
30-
struct Collector {
31-
// Amount of tokens the collector is allowed to collect
32-
uint256 allowance;
33-
// Timestamp at which the collector thawing period ends (zero if not thawing)
34-
uint256 thawEndTimestamp;
35-
}
36-
37-
/**
38-
* @notice Emitted when a payer authorizes a collector to collect funds
39-
* @param payer The address of the payer
40-
* @param collector The address of the collector
41-
* @param addedAllowance The amount of tokens added to the collector's allowance
42-
* @param newTotalAllowance The new total allowance after addition
43-
*/
44-
event AuthorizedCollector(
45-
address indexed payer,
46-
address indexed collector,
47-
uint256 addedAllowance,
48-
uint256 newTotalAllowance
49-
);
50-
51-
/**
52-
* @notice Emitted when a payer thaws a collector
53-
* @param payer The address of the payer
54-
* @param collector The address of the collector
55-
*/
56-
event ThawCollector(address indexed payer, address indexed collector);
57-
58-
/**
59-
* @notice Emitted when a payer cancels the thawing of a collector
60-
* @param payer The address of the payer
61-
* @param collector The address of the collector
62-
*/
63-
event CancelThawCollector(address indexed payer, address indexed collector);
64-
65-
/**
66-
* @notice Emitted when a payer revokes a collector authorization.
67-
* @param payer The address of the payer
68-
* @param collector The address of the collector
69-
*/
70-
event RevokeCollector(address indexed payer, address indexed collector);
71-
7228
/**
7329
* @notice Emitted when a payer deposits funds into the escrow for a payer-collector-receiver tuple
7430
* @param payer The address of the payer
@@ -152,13 +108,6 @@ interface IPaymentsEscrow {
152108
*/
153109
error PaymentsEscrowThawingPeriodTooLong(uint256 thawingPeriod, uint256 maxWaitPeriod);
154110

155-
/**
156-
* @notice Thrown when a collector has insufficient allowance to collect funds
157-
* @param allowance The current allowance
158-
* @param minAllowance The minimum required allowance
159-
*/
160-
error PaymentsEscrowInsufficientAllowance(uint256 allowance, uint256 minAllowance);
161-
162111
/**
163112
* @notice Thrown when the contract balance is not consistent with the collection amount
164113
* @param balanceBefore The balance before the collection
@@ -172,54 +121,6 @@ interface IPaymentsEscrow {
172121
*/
173122
error PaymentsEscrowInvalidZeroTokens();
174123

175-
/**
176-
* @notice Authorize a collector to collect funds from the payer's escrow
177-
* @dev This function can only be used to increase the allowance of a collector.
178-
* To reduce it the authorization must be revoked and a new one must be created.
179-
*
180-
* Requirements:
181-
* - `allowance` must be greater than zero
182-
*
183-
* Emits an {AuthorizedCollector} event
184-
*
185-
* @param collector The address of the collector
186-
* @param allowance The amount of tokens to add to the collector's allowance
187-
*/
188-
function approveCollector(address collector, uint256 allowance) external;
189-
190-
/**
191-
* @notice Thaw a collector's collector authorization
192-
* @dev The thawing period is defined by the `REVOKE_COLLECTOR_THAWING_PERIOD` constant
193-
*
194-
* Emits a {ThawCollector} event
195-
*
196-
* @param collector The address of the collector
197-
*/
198-
function thawCollector(address collector) external;
199-
200-
/**
201-
* @notice Cancel a collector's authorization thawing
202-
* @dev Requirements:
203-
* - `collector` must be thawing
204-
*
205-
* Emits a {CancelThawCollector} event
206-
*
207-
* @param collector The address of the collector
208-
*/
209-
function cancelThawCollector(address collector) external;
210-
211-
/**
212-
* @notice Revoke a collector's authorization.
213-
* Removes the collector from the list of authorized collectors.
214-
* @dev Requirements:
215-
* - `collector` must have thawed
216-
*
217-
* Emits a {RevokeCollector} event
218-
*
219-
* @param collector The address of the collector
220-
*/
221-
function revokeCollector(address collector) external;
222-
223124
/**
224125
* @notice Deposits funds into the escrow for a payer-collector-receiver tuple, where
225126
* the payer is the transaction caller.
@@ -277,8 +178,6 @@ interface IPaymentsEscrow {
277178
* @notice Collects funds from the payer-collector-receiver's escrow and sends them to {GraphPayments} for
278179
* distribution using the Graph Horizon Payments protocol.
279180
* The function will revert if there are not enough funds in the escrow.
280-
* @dev Requirements:
281-
* - `collector` needs to be authorized by the payer and have enough allowance
282181
*
283182
* Emits an {EscrowCollected} event
284183
*

packages/horizon/contracts/payments/PaymentsEscrow.sol

Lines changed: 2 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,6 @@ import { GraphDirectory } from "../utilities/GraphDirectory.sol";
2323
contract PaymentsEscrow is Initializable, MulticallUpgradeable, GraphDirectory, IPaymentsEscrow {
2424
using TokenUtils for IGraphToken;
2525

26-
/// @notice Authorization details for payer-collector pairs
27-
mapping(address payer => mapping(address collector => IPaymentsEscrow.Collector collectorDetails))
28-
public authorizedCollectors;
29-
3026
/// @notice Escrow account details for payer-collector-receiver tuples
3127
mapping(address payer => mapping(address collector => mapping(address receiver => IPaymentsEscrow.EscrowAccount escrowAccount)))
3228
public escrowAccounts;
@@ -35,9 +31,6 @@ contract PaymentsEscrow is Initializable, MulticallUpgradeable, GraphDirectory,
3531
/// @dev This is a precautionary measure to avoid inadvertedly locking funds for too long
3632
uint256 public constant MAX_WAIT_PERIOD = 90 days;
3733

38-
/// @notice Thawing period in seconds for authorized collectors
39-
uint256 public immutable REVOKE_COLLECTOR_THAWING_PERIOD;
40-
4134
/// @notice Thawing period in seconds for escrow funds withdrawal
4235
uint256 public immutable WITHDRAW_ESCROW_THAWING_PERIOD;
4336

@@ -49,24 +42,14 @@ contract PaymentsEscrow is Initializable, MulticallUpgradeable, GraphDirectory,
4942
/**
5043
* @notice Construct the PaymentsEscrow contract
5144
* @param controller The address of the controller
52-
* @param revokeCollectorThawingPeriod Thawing period in seconds for authorized collectors
5345
* @param withdrawEscrowThawingPeriod Thawing period in seconds for escrow funds withdrawal
5446
*/
55-
constructor(
56-
address controller,
57-
uint256 revokeCollectorThawingPeriod,
58-
uint256 withdrawEscrowThawingPeriod
59-
) GraphDirectory(controller) {
60-
require(
61-
revokeCollectorThawingPeriod <= MAX_WAIT_PERIOD,
62-
PaymentsEscrowThawingPeriodTooLong(revokeCollectorThawingPeriod, MAX_WAIT_PERIOD)
63-
);
47+
constructor(address controller, uint256 withdrawEscrowThawingPeriod) GraphDirectory(controller) {
6448
require(
6549
withdrawEscrowThawingPeriod <= MAX_WAIT_PERIOD,
6650
PaymentsEscrowThawingPeriodTooLong(withdrawEscrowThawingPeriod, MAX_WAIT_PERIOD)
6751
);
6852

69-
REVOKE_COLLECTOR_THAWING_PERIOD = revokeCollectorThawingPeriod;
7053
WITHDRAW_ESCROW_THAWING_PERIOD = withdrawEscrowThawingPeriod;
7154
}
7255

@@ -77,52 +60,6 @@ contract PaymentsEscrow is Initializable, MulticallUpgradeable, GraphDirectory,
7760
__Multicall_init();
7861
}
7962

80-
/**
81-
* @notice See {IPaymentsEscrow-approveCollector}
82-
*/
83-
function approveCollector(address collector_, uint256 allowance) external override notPaused {
84-
require(allowance != 0, PaymentsEscrowInvalidZeroTokens());
85-
Collector storage collector = authorizedCollectors[msg.sender][collector_];
86-
collector.allowance += allowance;
87-
emit AuthorizedCollector(msg.sender, collector_, allowance, collector.allowance);
88-
}
89-
90-
/**
91-
* @notice See {IPaymentsEscrow-thawCollector}
92-
*/
93-
function thawCollector(address collector) external override notPaused {
94-
authorizedCollectors[msg.sender][collector].thawEndTimestamp =
95-
block.timestamp +
96-
REVOKE_COLLECTOR_THAWING_PERIOD;
97-
emit ThawCollector(msg.sender, collector);
98-
}
99-
100-
/**
101-
* @notice See {IPaymentsEscrow-cancelThawCollector}
102-
*/
103-
function cancelThawCollector(address collector) external override notPaused {
104-
require(authorizedCollectors[msg.sender][collector].thawEndTimestamp != 0, PaymentsEscrowNotThawing());
105-
106-
authorizedCollectors[msg.sender][collector].thawEndTimestamp = 0;
107-
emit CancelThawCollector(msg.sender, collector);
108-
}
109-
110-
/**
111-
* @notice See {IPaymentsEscrow-revokeCollector}
112-
*/
113-
function revokeCollector(address collector_) external override notPaused {
114-
Collector storage collector = authorizedCollectors[msg.sender][collector_];
115-
116-
require(collector.thawEndTimestamp != 0, PaymentsEscrowNotThawing());
117-
require(
118-
collector.thawEndTimestamp < block.timestamp,
119-
PaymentsEscrowStillThawing(block.timestamp, collector.thawEndTimestamp)
120-
);
121-
122-
delete authorizedCollectors[msg.sender][collector_];
123-
emit RevokeCollector(msg.sender, collector_);
124-
}
125-
12663
/**
12764
* @notice See {IPaymentsEscrow-deposit}
12865
*/
@@ -194,19 +131,11 @@ contract PaymentsEscrow is Initializable, MulticallUpgradeable, GraphDirectory,
194131
address dataService,
195132
uint256 tokensDataService
196133
) external override notPaused {
197-
// Check if collector is authorized and has enough funds
198-
Collector storage collectorDetails = authorizedCollectors[payer][msg.sender];
199-
require(
200-
collectorDetails.allowance >= tokens,
201-
PaymentsEscrowInsufficientAllowance(collectorDetails.allowance, tokens)
202-
);
203-
204134
// Check if there are enough funds in the escrow account
205135
EscrowAccount storage account = escrowAccounts[payer][msg.sender][receiver];
206136
require(account.balance >= tokens, PaymentsEscrowInsufficientBalance(account.balance, tokens));
207137

208-
// Reduce amount from approved collector and account balance
209-
collectorDetails.allowance -= tokens;
138+
// Reduce amount from account balance
210139
account.balance -= tokens;
211140

212141
uint256 balanceBefore = _graphToken().balanceOf(address(this));

packages/horizon/ignition/configs/horizon.hardhat.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,6 @@
3636
"protocolPaymentCut": 10000
3737
},
3838
"PaymentsEscrow": {
39-
"revokeCollectorThawingPeriod": 10000,
4039
"withdrawEscrowThawingPeriod": 10000
4140
},
4241
"TAPCollector": {

packages/horizon/ignition/modules/core/PaymentsEscrow.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,12 @@ export default buildModule('PaymentsEscrow', (m) => {
1010
const { Controller, PeripheryRegistered } = m.useModule(GraphPeripheryModule)
1111
const { PaymentsEscrowProxyAdmin, PaymentsEscrowProxy, HorizonRegistered } = m.useModule(HorizonProxiesModule)
1212

13-
const revokeCollectorThawingPeriod = m.getParameter('revokeCollectorThawingPeriod')
1413
const withdrawEscrowThawingPeriod = m.getParameter('withdrawEscrowThawingPeriod')
1514

1615
// Deploy PaymentsEscrow implementation
1716
const PaymentsEscrowImplementation = m.contract('PaymentsEscrow',
1817
PaymentsEscrowArtifact,
19-
[Controller, revokeCollectorThawingPeriod, withdrawEscrowThawingPeriod],
18+
[Controller, withdrawEscrowThawingPeriod],
2019
{
2120
after: [PeripheryRegistered, HorizonRegistered],
2221
},

packages/horizon/test/GraphBase.t.sol

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ abstract contract GraphBaseTest is IHorizonStakingTypes, Utils, Constants {
116116
// PaymentsEscrow
117117
bytes memory escrowImplementationParameters = abi.encode(
118118
address(controller),
119-
revokeCollectorThawingPeriod,withdrawEscrowThawingPeriod
119+
withdrawEscrowThawingPeriod
120120
);
121121
bytes memory escrowImplementationBytecode = abi.encodePacked(
122122
type(PaymentsEscrow).creationCode,

packages/horizon/test/escrow/GraphEscrow.t.sol

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,6 @@ contract GraphEscrowTest is HorizonStakingSharedTest, PaymentsEscrowSharedTest {
2424
_;
2525
}
2626

27-
modifier useCollector(uint256 tokens) {
28-
vm.assume(tokens > 0);
29-
escrow.approveCollector(users.verifier, tokens);
30-
_;
31-
}
32-
3327
modifier depositAndThawTokens(uint256 amount, uint256 thawAmount) {
3428
vm.assume(thawAmount > 0);
3529
vm.assume(amount > thawAmount);

packages/horizon/test/escrow/collect.t.sol

Lines changed: 2 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -106,47 +106,17 @@ contract GraphEscrowCollectTest is GraphEscrowTest {
106106
_delegate(users.indexer, subgraphDataServiceAddress, delegationTokens, 0);
107107

108108
resetPrank(users.gateway);
109-
escrow.approveCollector(users.verifier, tokens);
110109
_depositTokens(users.verifier, users.indexer, tokens);
111110

112111
resetPrank(users.verifier);
113112
_collect(IGraphPayments.PaymentTypes.QueryFee, users.gateway, users.indexer, tokens, subgraphDataServiceAddress, tokensDataService);
114113
}
115114

116-
function testCollect_RevertWhen_CollectorNotAuthorized(uint256 amount) public {
117-
vm.assume(amount > 0);
118-
vm.startPrank(users.verifier);
119-
uint256 dataServiceCut = 30000; // 3%
120-
bytes memory expectedError = abi.encodeWithSelector(
121-
IPaymentsEscrow.PaymentsEscrowInsufficientAllowance.selector,
122-
0,
123-
amount
124-
);
125-
vm.expectRevert(expectedError);
126-
escrow.collect(IGraphPayments.PaymentTypes.QueryFee, users.gateway, users.indexer, amount, subgraphDataServiceAddress, dataServiceCut);
127-
vm.stopPrank();
128-
}
129-
130-
function testCollect_RevertWhen_CollectorHasInsufficientAmount(
131-
uint256 amount,
132-
uint256 insufficientAmount
133-
) public useGateway useCollector(insufficientAmount) useDeposit(amount) {
134-
vm.assume(insufficientAmount < amount);
135-
136-
vm.startPrank(users.verifier);
137-
bytes memory expectedError = abi.encodeWithSignature(
138-
"PaymentsEscrowInsufficientAllowance(uint256,uint256)",
139-
insufficientAmount,
140-
amount
141-
);
142-
vm.expectRevert(expectedError);
143-
escrow.collect(IGraphPayments.PaymentTypes.QueryFee, users.gateway, users.indexer, amount, subgraphDataServiceAddress, 0);
144-
}
145-
146115
function testCollect_RevertWhen_SenderHasInsufficientAmountInEscrow(
147116
uint256 amount,
148117
uint256 insufficientAmount
149-
) public useGateway useCollector(amount) useDeposit(insufficientAmount) {
118+
) public useGateway useDeposit(insufficientAmount) {
119+
vm.assume(amount > 0);
150120
vm.assume(insufficientAmount < amount);
151121

152122
vm.startPrank(users.verifier);
@@ -162,7 +132,6 @@ contract GraphEscrowCollectTest is GraphEscrowTest {
162132
vm.assume(amount > 1 ether);
163133

164134
resetPrank(users.gateway);
165-
escrow.approveCollector(users.verifier, amount);
166135
_depositTokens(users.verifier, users.indexer, amount);
167136

168137
resetPrank(users.verifier);
@@ -181,7 +150,6 @@ contract GraphEscrowCollectTest is GraphEscrowTest {
181150
vm.assume(amount <= MAX_STAKING_TOKENS);
182151

183152
resetPrank(users.gateway);
184-
escrow.approveCollector(users.verifier, amount);
185153
_depositTokens(users.verifier, users.indexer, amount);
186154

187155
resetPrank(users.verifier);

0 commit comments

Comments
 (0)