Skip to content

Commit 8fe5101

Browse files
committed
update withdrawal logic
1 parent e89de67 commit 8fe5101

File tree

2 files changed

+67
-55
lines changed

2 files changed

+67
-55
lines changed

contracts/src/Payer.sol

+42-33
Original file line numberDiff line numberDiff line change
@@ -50,29 +50,25 @@ contract Payer is
5050

5151
/// @custom:storage-location erc7201:xmtp.storage.Payer
5252
struct PayerStorage {
53-
// 1. Configuration and state parameters packed in 2 slots.
53+
// Configuration and state parameters (fits in 2 slots)
5454
uint64 minimumRegistrationAmountMicroDollars; // 8 bytes
5555
uint64 minimumDepositAmountMicroDollars; // 8 bytes
5656
uint64 maxTolerableDebtAmountMicroDollars; // 8 bytes
5757
uint64 lastFeeTransferTimestamp; // 8 bytes
58-
5958
uint64 totalAmountDeposited; // 8 bytes
6059
uint64 totalDebtAmount; // 8 bytes
6160
uint64 pendingFees; // 8 bytes
6261
uint64 collectedFees; // 8 bytes
63-
6462
uint32 withdrawalLockPeriod; // 4 bytes
6563
uint32 transferFeesPeriod; // 4 bytes
66-
uint32 reserved1; // 4 bytes (reserved for future use)
67-
uint32 reserved2; // 4 bytes (reserved for future use)
6864

69-
// 2. Contract addresses (each 20 bytes, fits in 3 slots)
65+
// Contract addresses (fits in 3 slots)
7066
IERC20 usdcToken; // 20 bytes
7167
address distributionContract; // 20 bytes
7268
address nodesContract; // 20 bytes
7369
address payerReportContract; // 20 bytes
7470

75-
// 3. Mappings and dynamic sets (each starts at its own storage slot)
71+
// Mappings and dynamic sets (each starts at its own storage slot)
7672
mapping(address => Payer) payers;
7773
mapping(address => Withdrawal) withdrawals;
7874
EnumerableSet.AddressSet totalPayers;
@@ -237,7 +233,7 @@ contract Payer is
237233
require($.totalPayers.remove(payer), FailedToDeletePayer());
238234
require($.activePayers.remove(payer), FailedToDeletePayer());
239235

240-
emit PayerDeleted(payer, block.timestamp);
236+
emit PayerDeleted(payer, uint64(block.timestamp));
241237
}
242238

243239
/* ========== Payers Balance Management ========= */
@@ -260,15 +256,17 @@ contract Payer is
260256
$.payers[msg.sender].balance -= amount;
261257
_decreaseTotalAmountDeposited(amount);
262258

263-
uint256 withdrawableTimestamp = block.timestamp + $.withdrawalLockPeriod;
259+
emit PayerBalanceUpdated(msg.sender, $.payers[msg.sender].balance, $.payers[msg.sender].debtAmount);
260+
261+
uint64 withdrawableTimestamp = uint64(block.timestamp) + $.withdrawalLockPeriod;
264262

265263
$.withdrawals[msg.sender] = Withdrawal({
266264
requestTimestamp: uint64(block.timestamp),
267-
withdrawableTimestamp: uint64(withdrawableTimestamp),
265+
withdrawableTimestamp: withdrawableTimestamp,
268266
amount: amount
269267
});
270268

271-
emit WithdrawalRequested(msg.sender, block.timestamp, withdrawableTimestamp, amount);
269+
emit WithdrawalRequested(msg.sender, uint64(block.timestamp), withdrawableTimestamp, amount);
272270
}
273271

274272
/**
@@ -286,6 +284,8 @@ contract Payer is
286284
$.payers[msg.sender].balance += _withdrawal.amount;
287285
_increaseTotalAmountDeposited(_withdrawal.amount);
288286

287+
emit PayerBalanceUpdated(msg.sender, $.payers[msg.sender].balance, $.payers[msg.sender].debtAmount);
288+
289289
emit WithdrawalCancelled(msg.sender, _withdrawal.requestTimestamp);
290290
}
291291

@@ -299,18 +299,22 @@ contract Payer is
299299

300300
Withdrawal memory _withdrawal = $.withdrawals[msg.sender];
301301

302+
require(block.timestamp >= _withdrawal.withdrawableTimestamp, WithdrawalPeriodNotElapsed());
303+
302304
delete $.withdrawals[msg.sender];
303305

304-
uint256 _finalWithdrawalAmount = _withdrawal.amount;
306+
uint64 _finalWithdrawalAmount = _withdrawal.amount;
305307

306308
if ($.payers[msg.sender].debtAmount > 0) {
307-
_finalWithdrawalAmount = _settleDebts(msg.sender, _withdrawal.amount);
309+
_finalWithdrawalAmount = _settleDebts(msg.sender, _withdrawal.amount, true);
308310
}
309311

310312
if (_finalWithdrawalAmount > 0) {
311313
$.usdcToken.safeTransfer(msg.sender, _finalWithdrawalAmount);
312314
}
313315

316+
emit PayerBalanceUpdated(msg.sender, $.payers[msg.sender].balance, $.payers[msg.sender].debtAmount);
317+
314318
emit WithdrawalFinalized(msg.sender, _withdrawal.requestTimestamp, _finalWithdrawalAmount);
315319
}
316320

@@ -383,7 +387,7 @@ contract Payer is
383387

384388
$.pendingFees = _pendingFees;
385389

386-
emit UsageSettled(originatorNode, block.timestamp, _settledFees);
390+
emit UsageSettled(originatorNode, uint64(block.timestamp), _settledFees);
387391
}
388392

389393
/**
@@ -408,7 +412,7 @@ contract Payer is
408412
$.collectedFees += _pendingFeesAmount;
409413
$.pendingFees = 0;
410414

411-
emit FeesTransferred(block.timestamp, _pendingFeesAmount);
415+
emit FeesTransferred(uint64(block.timestamp), _pendingFeesAmount);
412416
}
413417

414418
/* ========== Administrative Functions ========== */
@@ -449,7 +453,7 @@ contract Payer is
449453

450454
PayerStorage storage $ = _getPayerStorage();
451455

452-
uint256 oldMinimumDeposit = $.minimumDepositAmountMicroDollars;
456+
uint64 oldMinimumDeposit = $.minimumDepositAmountMicroDollars;
453457
$.minimumDepositAmountMicroDollars = newMinimumDeposit;
454458

455459
emit MinimumDepositSet(oldMinimumDeposit, newMinimumDeposit);
@@ -466,7 +470,7 @@ contract Payer is
466470

467471
PayerStorage storage $ = _getPayerStorage();
468472

469-
uint256 _oldMinimumRegistrationAmount = $.minimumRegistrationAmountMicroDollars;
473+
uint64 _oldMinimumRegistrationAmount = $.minimumRegistrationAmountMicroDollars;
470474
$.minimumRegistrationAmountMicroDollars = newMinimumRegistrationAmount;
471475

472476
emit MinimumRegistrationAmountSet(_oldMinimumRegistrationAmount, newMinimumRegistrationAmount);
@@ -480,7 +484,7 @@ contract Payer is
480484

481485
PayerStorage storage $ = _getPayerStorage();
482486

483-
uint256 _oldWithdrawalLockPeriod = $.withdrawalLockPeriod;
487+
uint32 _oldWithdrawalLockPeriod = $.withdrawalLockPeriod;
484488
$.withdrawalLockPeriod = newWithdrawalLockPeriod;
485489

486490
emit WithdrawalLockPeriodSet(_oldWithdrawalLockPeriod, newWithdrawalLockPeriod);
@@ -542,7 +546,7 @@ contract Payer is
542546
/**
543547
* @inheritdoc IPayer
544548
*/
545-
function getActivePayers(uint256 offset, uint256 limit)
549+
function getActivePayers(uint32 offset, uint32 limit)
546550
external
547551
view
548552
returns (Payer[] memory payers, bool hasMore)
@@ -571,7 +575,7 @@ contract Payer is
571575
/**
572576
* @inheritdoc IPayer
573577
*/
574-
function getPayerBalance(address payer) external view returns (uint256 balance) {
578+
function getPayerBalance(address payer) external view returns (uint64 balance) {
575579
_revertIfPayerDoesNotExist(payer);
576580

577581
return _getPayerStorage().payers[payer].balance;
@@ -580,7 +584,7 @@ contract Payer is
580584
/**
581585
* @inheritdoc IPayer
582586
*/
583-
function getPayersInDebt(uint256 offset, uint256 limit)
587+
function getPayersInDebt(uint32 offset, uint32 limit)
584588
external
585589
view
586590
returns (Payer[] memory payers, bool hasMore)
@@ -614,14 +618,14 @@ contract Payer is
614618
/**
615619
* @inheritdoc IPayer
616620
*/
617-
function getLastFeeTransferTimestamp() external view returns (uint256 timestamp) {
621+
function getLastFeeTransferTimestamp() external view returns (uint64 timestamp) {
618622
return _getPayerStorage().lastFeeTransferTimestamp;
619623
}
620624

621625
/**
622626
* @inheritdoc IPayer
623627
*/
624-
function getTotalValueLocked() external view returns (uint256 totalValueLocked) {
628+
function getTotalValueLocked() external view returns (uint64 totalValueLocked) {
625629
PayerStorage storage $ = _getPayerStorage();
626630

627631
if ($.totalDebtAmount > $.totalAmountDeposited) return 0;
@@ -632,7 +636,7 @@ contract Payer is
632636
/**
633637
* @inheritdoc IPayer
634638
*/
635-
function getTotalDebtAmount() external view returns (uint256 totalDebt) {
639+
function getTotalDebtAmount() external view returns (uint64 totalDebt) {
636640
return _getPayerStorage().totalDebtAmount;
637641
}
638642

@@ -667,28 +671,28 @@ contract Payer is
667671
/**
668672
* @inheritdoc IPayer
669673
*/
670-
function getMinimumDeposit() external view returns (uint256 minimumDeposit) {
674+
function getMinimumDeposit() external view returns (uint64 minimumDeposit) {
671675
return _getPayerStorage().minimumDepositAmountMicroDollars;
672676
}
673677

674678
/**
675679
* @inheritdoc IPayer
676680
*/
677-
function getMinimumRegistrationAmount() external view returns (uint256 minimumRegistrationAmount) {
681+
function getMinimumRegistrationAmount() external view returns (uint64 minimumRegistrationAmount) {
678682
return _getPayerStorage().minimumRegistrationAmountMicroDollars;
679683
}
680684

681685
/**
682686
* @inheritdoc IPayer
683687
*/
684-
function getWithdrawalLockPeriod() external view returns (uint256 lockPeriod) {
688+
function getWithdrawalLockPeriod() external view returns (uint32 lockPeriod) {
685689
return _getPayerStorage().withdrawalLockPeriod;
686690
}
687691

688692
/**
689693
* @inheritdoc IPayer
690694
*/
691-
function getPendingFees() external view returns (uint256 fees) {
695+
function getPendingFees() external view returns (uint64 fees) {
692696
return _getPayerStorage().pendingFees;
693697
}
694698

@@ -719,11 +723,11 @@ contract Payer is
719723
* @param amount The amount to add to the payer's balance.
720724
* @return leftoverAmount Amount remaining after debt settlement (if any).
721725
*/
722-
function _updatePayerBalance(address payerAddress, uint64 amount) internal returns (uint256 leftoverAmount) {
726+
function _updatePayerBalance(address payerAddress, uint64 amount) internal returns (uint64 leftoverAmount) {
723727
Payer storage _payer = _getPayerStorage().payers[payerAddress];
724728

725729
if (_payer.debtAmount > 0) {
726-
return _settleDebts(payerAddress, amount);
730+
return _settleDebts(payerAddress, amount, false);
727731
} else {
728732
_payer.balance += amount;
729733
_increaseTotalAmountDeposited(amount);
@@ -735,9 +739,10 @@ contract Payer is
735739
* @notice Settles debts for a payer, updating their balance and total amounts.
736740
* @param payer The address of the payer.
737741
* @param amount The amount to settle debts for.
742+
* @param isWithdrawal Whether the debt settlement happens during a withdrawal.
738743
* @return amountAfterSettlement The amount remaining after debt settlement.
739744
*/
740-
function _settleDebts(address payer, uint64 amount) internal returns (uint256 amountAfterSettlement) {
745+
function _settleDebts(address payer, uint64 amount, bool isWithdrawal) internal returns (uint64 amountAfterSettlement) {
741746
PayerStorage storage $ = _getPayerStorage();
742747

743748
Payer memory _storedPayer = $.payers[payer];
@@ -746,8 +751,12 @@ contract Payer is
746751
uint64 _debtToRemove = _storedPayer.debtAmount;
747752
amount -= _debtToRemove;
748753

749-
_storedPayer.debtAmount = 0;
750-
_storedPayer.balance += amount;
754+
// For regular deposits, add remaining amount to balance.
755+
// In withdrawals, that amount was moved to the withdrawal balance.
756+
if (!isWithdrawal) {
757+
_storedPayer.balance += amount;
758+
_increaseTotalAmountDeposited(amount);
759+
}
751760

752761
_removeDebtor(payer);
753762
_increaseTotalAmountDeposited(amount);

0 commit comments

Comments
 (0)