From 4e779029a8dedccc398e7af04800cdc8ed937371 Mon Sep 17 00:00:00 2001 From: mike Date: Mon, 16 Dec 2024 16:28:30 +0100 Subject: [PATCH] Refactor burn native tokens method --- contracts/sfc/SFC.sol | 22 +++++++++++++--------- test/SFC.ts | 22 +++++++++++++++++++++- 2 files changed, 34 insertions(+), 10 deletions(-) diff --git a/contracts/sfc/SFC.sol b/contracts/sfc/SFC.sol index 159f91f..ab2a5a6 100644 --- a/contracts/sfc/SFC.sol +++ b/contracts/sfc/SFC.sol @@ -216,7 +216,7 @@ contract SFC is OwnableUpgradeable, UUPSUpgradeable, Version { ); event ClaimedRewards(address indexed delegator, uint256 indexed toValidatorID, uint256 rewards); event RestakedRewards(address indexed delegator, uint256 indexed toValidatorID, uint256 rewards); - event BurntFTM(uint256 amount); + event BurntNativeTokens(uint256 amount); event UpdatedSlashingRefundRatio(uint256 indexed validatorID, uint256 refundRatio); event RefundedSlashedLegacyDelegation(address indexed delegator, uint256 indexed validatorID, uint256 amount); event AnnouncedRedirection(address indexed from, address indexed to); @@ -459,9 +459,12 @@ contract SFC is OwnableUpgradeable, UUPSUpgradeable, Version { emit TreasuryFeesResolved(fees); } - /// burnFTM allows SFC to burn an arbitrary amount of FTM tokens. - function burnFTM(uint256 amount) external onlyOwner { - _burnFTM(amount); + /// Burn native tokens by sending them to the SFC contract. + function burnNativeTokens() external payable { + if (msg.value == 0) { + revert ZeroAmount(); + } + _burnNativeTokens(msg.value); } /// Issue tokens to the issued tokens recipient as a counterparty to the burnt FTM tokens. @@ -753,7 +756,7 @@ contract SFC is OwnableUpgradeable, UUPSUpgradeable, Version { if (!sent) { revert TransferFailed(); } - _burnFTM(penalty); + _burnNativeTokens(penalty); emit Withdrawn(delegator, toValidatorID, wrID, amount - penalty, penalty); } @@ -817,12 +820,13 @@ contract SFC is OwnableUpgradeable, UUPSUpgradeable, Version { return rewards; } - /// Burn FTM tokens. + /// Burn native tokens. /// The tokens are sent to the zero address. - function _burnFTM(uint256 amount) internal { - if (amount != 0) { + function _burnNativeTokens(uint256 amount) internal { + if (amount != 0 && totalSupply >= amount) { + totalSupply -= amount; payable(address(0)).transfer(amount); - emit BurntFTM(amount); + emit BurntNativeTokens(amount); } } diff --git a/test/SFC.ts b/test/SFC.ts index b3ea8d6..4d7cfbc 100644 --- a/test/SFC.ts +++ b/test/SFC.ts @@ -24,7 +24,7 @@ describe('SFC', () => { const evmWriter: IEVMWriter = await ethers.deployContract('StubEvmWriter'); const initializer: UnitTestNetworkInitializer = await ethers.deployContract('UnitTestNetworkInitializer'); - await initializer.initializeAll(0, 0, sfc, nodeDriverAuth, nodeDriver, evmWriter, owner); + await initializer.initializeAll(0, ethers.parseEther('100000'), sfc, nodeDriverAuth, nodeDriver, evmWriter, owner); const constants: UnitTestConstantsManager = await ethers.getContractAt( 'UnitTestConstantsManager', await sfc.constsAddress(), @@ -55,6 +55,26 @@ describe('SFC', () => { ).to.revertedWithCustomError(this.sfc, 'TransfersNotAllowed'); }); + describe('Burn native tokens', () => { + it('Should revert when no amount sent', async function () { + await expect(this.sfc.connect(this.user).burnNativeTokens()).to.be.revertedWithCustomError( + this.sfc, + 'ZeroAmount', + ); + }); + + it('Should succeed and burn native tokens', async function () { + const amount = ethers.parseEther('1.5'); + const totalSupply = await this.sfc.totalSupply(); + const tx = await this.sfc.connect(this.user).burnNativeTokens({ value: amount }); + await expect(tx).to.emit(this.sfc, 'BurntNativeTokens').withArgs(amount); + expect(await this.sfc.totalSupply()).to.equal(totalSupply - amount); + await expect(tx).to.changeEtherBalance(this.sfc, 0); + await expect(tx).to.changeEtherBalance(this.user, -amount); + await expect(tx).to.changeEtherBalance(ethers.ZeroAddress, amount); + }); + }); + describe('Genesis validator', () => { beforeEach(async function () { const validator = ethers.Wallet.createRandom();