diff --git a/packages/smart-contracts/src/contracts/ERC20RecurringPaymentProxy.sol b/packages/smart-contracts/src/contracts/ERC20RecurringPaymentProxy.sol index a84305baf..6be6e597b 100644 --- a/packages/smart-contracts/src/contracts/ERC20RecurringPaymentProxy.sol +++ b/packages/smart-contracts/src/contracts/ERC20RecurringPaymentProxy.sol @@ -58,6 +58,18 @@ contract ERC20RecurringPaymentProxy is EIP712, AccessControl, Pausable, Reentran mapping(bytes32 => bool) public cancelledSchedules; mapping(bytes32 => uint256) public admittedCycles; + event PaymentTriggered( + bytes32 indexed scheduleKey, + address indexed subscriber, + address token, + uint8 index, + uint256 payerTotal + ); + event ScheduleCancelled(bytes32 indexed scheduleKey, address indexed subscriber); + event CyclesAdmitted(bytes32 indexed scheduleKey, uint256 mask); + event CyclesRevoked(bytes32 indexed scheduleKey, uint256 mask); + event FeeProxyUpdated(address indexed oldProxy, address indexed newProxy); + IERC20FeeProxy public erc20FeeProxy; struct Leg { @@ -199,6 +211,7 @@ contract ERC20RecurringPaymentProxy is EIP712, AccessControl, Pausable, Reentran function admitCycles(bytes32 scheduleKey, uint256 mask) external onlyRole(RELAYER_ROLE) { admittedCycles[scheduleKey] |= mask; + emit CyclesAdmitted(scheduleKey, mask); } /** @@ -207,6 +220,7 @@ contract ERC20RecurringPaymentProxy is EIP712, AccessControl, Pausable, Reentran */ function revokeCycles(bytes32 scheduleKey, uint256 mask) external onlyRole(RELAYER_ROLE) { admittedCycles[scheduleKey] &= ~mask; + emit CyclesRevoked(scheduleKey, mask); } function _assertUnpaid(bytes32 scheduleKey, uint8 index) private view { @@ -374,6 +388,7 @@ contract ERC20RecurringPaymentProxy is EIP712, AccessControl, Pausable, Reentran if (token.balanceOf(address(this)) != baseline) { revert ERC20RecurringPaymentProxy__UnexpectedBalance(); } + emit PaymentTriggered(scheduleKey, p.subscriber, p.token, index, payerTotal); } /** @@ -384,7 +399,9 @@ contract ERC20RecurringPaymentProxy is EIP712, AccessControl, Pausable, Reentran */ function cancelScheduleBatch(SchedulePermitBatch calldata p) external { _assertSubscriber(p.subscriber); - _cancel(_scheduleKeyFromBatch(p)); + bytes32 scheduleKey = _scheduleKeyFromBatch(p); + _cancel(scheduleKey); + emit ScheduleCancelled(scheduleKey, p.subscriber); } function setRelayer(address oldRelayer, address newRelayer) external onlyOwner { @@ -395,7 +412,9 @@ contract ERC20RecurringPaymentProxy is EIP712, AccessControl, Pausable, Reentran function setFeeProxy(address newProxy) external onlyOwner { if (newProxy == address(0)) revert ERC20RecurringPaymentProxy__ZeroAddress(); + address oldProxy = address(erc20FeeProxy); erc20FeeProxy = IERC20FeeProxy(newProxy); + emit FeeProxyUpdated(oldProxy, newProxy); } function pause() external onlyOwner { diff --git a/packages/smart-contracts/test/contracts/ERC20RecurringPaymentProxy.test.ts b/packages/smart-contracts/test/contracts/ERC20RecurringPaymentProxy.test.ts index 67c4c4e61..d8a984d9e 100644 --- a/packages/smart-contracts/test/contracts/ERC20RecurringPaymentProxy.test.ts +++ b/packages/smart-contracts/test/contracts/ERC20RecurringPaymentProxy.test.ts @@ -207,7 +207,9 @@ describe('ERC20RecurringPaymentProxy', () => { const newERC20FeeProxy = await (await ethers.getContractFactory('ERC20FeeProxy')).deploy(); await newERC20FeeProxy.deployed(); - await erc20RecurringPaymentProxy.setFeeProxy(newERC20FeeProxy.address); + await expect(erc20RecurringPaymentProxy.setFeeProxy(newERC20FeeProxy.address)) + .to.emit(erc20RecurringPaymentProxy, 'FeeProxyUpdated') + .withArgs(erc20FeeProxy.address, newERC20FeeProxy.address); expect(await erc20RecurringPaymentProxy.erc20FeeProxy()).to.equal(newERC20FeeProxy.address); }); @@ -488,7 +490,9 @@ describe('ERC20RecurringPaymentProxy', () => { ethers.utils.keccak256(ref(0x0b)), 0, ethers.constants.AddressZero, - ); + ) + .and.to.emit(erc20RecurringPaymentProxy, 'PaymentTriggered') + .withArgs(scheduleKey, subscriberAddress, token.address, 1, 34_000_000); expect(await token.balanceOf(subscriberAddress)).to.equal(subscriberBefore.sub(34_000_000)); expect(await token.balanceOf(recipientAddress)).to.equal(30_000_000); @@ -936,7 +940,10 @@ describe('ERC20RecurringPaymentProxy', () => { const permit = await simpleBatch(); const signature = await createBatchSignature(permit, subscriber); - await erc20RecurringPaymentProxy.connect(subscriber).cancelScheduleBatch(permit); + const scheduleKey = await erc20RecurringPaymentProxy.scheduleKeyFromBatch(permit); + await expect(erc20RecurringPaymentProxy.connect(subscriber).cancelScheduleBatch(permit)) + .to.emit(erc20RecurringPaymentProxy, 'ScheduleCancelled') + .withArgs(scheduleKey, subscriberAddress); await expect( erc20RecurringPaymentProxy @@ -998,7 +1005,9 @@ describe('ERC20RecurringPaymentProxy', () => { const signature = await createBatchSignature(permit, subscriber); const scheduleKey = await erc20RecurringPaymentProxy.scheduleKeyFromBatch(permit); - await erc20RecurringPaymentProxy.connect(relayer).admitCycles(scheduleKey, bit(3)); + await expect(erc20RecurringPaymentProxy.connect(relayer).admitCycles(scheduleKey, bit(3))) + .to.emit(erc20RecurringPaymentProxy, 'CyclesAdmitted') + .withArgs(scheduleKey, bit(3)); await expect( erc20RecurringPaymentProxy @@ -1113,7 +1122,9 @@ describe('ERC20RecurringPaymentProxy', () => { const scheduleKey = await erc20RecurringPaymentProxy.scheduleKeyFromBatch(permit); await erc20RecurringPaymentProxy.connect(relayer).admitCycles(scheduleKey, bit(3)); - await erc20RecurringPaymentProxy.connect(relayer).revokeCycles(scheduleKey, bit(3)); + await expect(erc20RecurringPaymentProxy.connect(relayer).revokeCycles(scheduleKey, bit(3))) + .to.emit(erc20RecurringPaymentProxy, 'CyclesRevoked') + .withArgs(scheduleKey, bit(3)); await expect( erc20RecurringPaymentProxy