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

Add option to issue tokens #105

Merged
merged 11 commits into from
Dec 16, 2024
8 changes: 8 additions & 0 deletions contracts/sfc/ConstantsManager.sol
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,10 @@ contract ConstantsManager is Ownable {
// Zero to disable validators deactivation by this metric.
uint64 public minAverageUptime;

// The address of the recipient that receives issued tokens
// as a counterparty to the burnt FTM tokens
address public issuedTokensRecipient;

/**
* @dev Given value is too small
*/
Expand Down Expand Up @@ -177,4 +181,8 @@ contract ConstantsManager is Ownable {
}
minAverageUptime = v;
}

function updateIssuedTokensRecipient(address v) external virtual onlyOwner {
issuedTokensRecipient = v;
}
}
3 changes: 0 additions & 3 deletions contracts/sfc/NodeDriverAuth.sol
Original file line number Diff line number Diff line change
Expand Up @@ -83,9 +83,6 @@ contract NodeDriverAuth is OwnableUpgradeable, UUPSUpgradeable {

/// Mint native token. To be used by SFC for minting validators rewards.
function incBalance(address acc, uint256 diff) external onlySFC {
if (acc != address(sfc)) {
revert RecipientNotSFC();
}
driver.setBalance(acc, address(acc).balance + diff);
}
Mike-CZ marked this conversation as resolved.
Show resolved Hide resolved

Expand Down
9 changes: 9 additions & 0 deletions contracts/sfc/SFC.sol
Original file line number Diff line number Diff line change
Expand Up @@ -459,6 +459,15 @@ contract SFC is OwnableUpgradeable, UUPSUpgradeable, Version {
_burnFTM(amount);
}

/// Issue tokens to the issued tokens recipient as a counterparty to the burnt FTM tokens.
function issueTokens(uint256 amount) external onlyOwner {
if (c.issuedTokensRecipient() == address(0)) {
revert ZeroAddress();
}
node.incBalance(c.issuedTokensRecipient(), amount);
totalSupply += amount;
}

/// Update treasury address.
function updateTreasuryAddress(address v) external onlyOwner {
treasuryAddress = v;
Expand Down
24 changes: 24 additions & 0 deletions test/SFC.ts
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,30 @@ describe('SFC', () => {
});
});

describe('Issue tokens', () => {
it('Should revert when not owner', async function () {
await expect(this.sfc.connect(this.user).issueTokens(ethers.parseEther('100'))).to.be.revertedWithCustomError(
this.sfc,
'OwnableUnauthorizedAccount',
);
});

it('Should revert when recipient is not set', async function () {
await expect(this.sfc.connect(this.owner).issueTokens(ethers.parseEther('100'))).to.be.revertedWithCustomError(
this.sfc,
'ZeroAddress',
);
});

it('Should succeed and issue tokens', async function () {
await this.constants.updateIssuedTokensRecipient(this.user);
const supply = await this.sfc.totalSupply();
const amount = ethers.parseEther('100');
await this.sfc.connect(this.owner).issueTokens(amount);
expect(await this.sfc.totalSupply()).to.equal(supply + amount);
});
});

describe('Create validator', () => {
const validatorsFixture = async () => {
const validatorPubKey =
Expand Down
Loading