-
-
Save BlockmanCodes/83d995ec9de0c4f5201c3556cba489e0 to your computer and use it in GitHub Desktop.
require("@nomiclabs/hardhat-waffle"); | |
/** | |
* @type import('hardhat/config').HardhatUserConfig | |
*/ | |
module.exports = { | |
solidity: "0.8.0", | |
}; |
{ | |
"name": "erc20-bank", | |
"version": "1.0.0", | |
"description": "", | |
"main": "index.js", | |
"scripts": { | |
"test": "echo \"Error: no test specified\" && exit 1" | |
}, | |
"keywords": [], | |
"author": "", | |
"license": "ISC", | |
"devDependencies": { | |
"@nomiclabs/hardhat-ethers": "^2.0.5", | |
"@nomiclabs/hardhat-waffle": "^2.0.3", | |
"chai": "^4.3.6", | |
"ethereum-waffle": "^3.4.0", | |
"ethers": "^5.5.4", | |
"hardhat": "^2.9.1" | |
}, | |
"dependencies": { | |
"@openzeppelin/contracts": "^4.5.0" | |
} | |
} |
const { expect } = require("chai"); | |
describe('Staking', function () { | |
beforeEach(async function() { | |
[owner, wallet1, wallet2] = await ethers.getSigners(); | |
Staking = await ethers.getContractFactory('Staking', owner); | |
Wbtc = await ethers.getContractFactory('Wbtc', wallet1); | |
staking = await Staking.deploy(); | |
wbtc = await Wbtc.deploy(); | |
wbtc.connect(wallet1).transfer(wallet2.address, 1000); | |
await wbtc.connect(wallet1).approve( | |
staking.address, | |
4000 | |
); | |
await wbtc.connect(wallet2).approve( | |
staking.address, | |
1000 | |
); | |
WBTC = ethers.utils.formatBytes32String('Wbtc'); | |
await staking.whitelistToken( | |
WBTC, | |
wbtc.address | |
); | |
}); | |
describe('deployment', function () { | |
it('should mint tokens to wallet 1', async function () { | |
expect(await wbtc.balanceOf(wallet1.address)).to.equal(4000); | |
}) | |
it('should transfer tokens to wallet 2', async function () { | |
expect(await wbtc.balanceOf(wallet2.address)).to.equal(1000); | |
}) | |
it('should whitelist wbtc on the contract', async function () { | |
expect( | |
await staking.whitelistedTokens(WBTC) | |
).to.equal(wbtc.address); | |
}) | |
}) | |
describe('depositTokens', function () { | |
it('should deposit wbtc', async function () { | |
await staking.connect(wallet1).depositTokens( | |
100, | |
WBTC, | |
); | |
await staking.connect(wallet2).depositTokens( | |
50, | |
WBTC, | |
); | |
expect(await wbtc.balanceOf(wallet1.address)).to.equal(3900); | |
expect(await wbtc.balanceOf(wallet2.address)).to.equal(950); | |
expect( | |
await staking.accountBalances(wallet1.address, WBTC) | |
).to.equal(100); | |
expect( | |
await staking.accountBalances(wallet2.address, WBTC) | |
).to.equal(50); | |
}); | |
}) | |
describe('withdraw', function () { | |
it('should withdraw wbtc from the contract', async function () { | |
await staking.connect(wallet1).depositTokens( | |
600, | |
WBTC, | |
); | |
await staking.connect(wallet1).withdrawTokens( | |
100, | |
WBTC, | |
); | |
expect(await wbtc.balanceOf(wallet1.address)).to.equal(3500); | |
expect( | |
await staking.accountBalances(wallet1.address, WBTC) | |
).to.equal(500); | |
}) | |
it('should not allow withdrawing more than has been deposited', async function () { | |
await expect( | |
staking.connect(wallet1).withdrawTokens(10000, WBTC) | |
).to.be.revertedWith("Insufficent funds") | |
}) | |
}) | |
}) |
// SPDX-License-Identifier: MIT | |
pragma solidity ^0.8.0; | |
import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; | |
contract Staking { | |
address owner; | |
mapping(bytes32 => address) public whitelistedTokens; | |
mapping(address => mapping(bytes32 => uint256)) public accountBalances; | |
constructor() { | |
owner = msg.sender; | |
} | |
function whitelistToken(bytes32 symbol, address tokenAddress) external { | |
require(msg.sender == owner, 'This function is not public'); | |
whitelistedTokens[symbol] = tokenAddress; | |
} | |
function getWhitelistedTokenAddresses(bytes32 token) external returns(address) { | |
return whitelistedTokens[token]; | |
} | |
function depositTokens(uint256 amount, bytes32 symbol) external { | |
accountBalances[msg.sender][symbol] += amount; | |
ERC20(whitelistedTokens[symbol]).transferFrom(msg.sender, address(this), amount); | |
} | |
function withdrawTokens(uint256 amount, bytes32 symbol) external { | |
require(accountBalances[msg.sender][symbol] >= amount, 'Insufficent funds'); | |
accountBalances[msg.sender][symbol] -= amount; | |
ERC20(whitelistedTokens[symbol]).transfer(msg.sender, amount); | |
} | |
} |
// SPDX-License-Identifier: MIT | |
pragma solidity ^0.8.0; | |
import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; | |
contract Wbtc is ERC20 { | |
constructor() ERC20('WBTC', 'Wrapped BTC') { | |
_mint(msg.sender, 5000); | |
} | |
} |
Thanks for the tutorial. Where does the
address()
method come from in line 27ERC20(whitelistedTokens[symbol]).transferFrom(msg.sender, address(this), amount);
in theStaking.sol
file?
It's core Solidity
Gas estimation errored with the following message (see below). The transaction execution will likely fail. Do you want to force sending? Internal JSON-RPC error. { "code": 3, "message": "execution reverted: ERC20: transfer amount exceeds allowance", "data": "0x08c379a00000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002845524332303a207472616e7366657220616d6f756e74206578636565647320616c6c6f77616e6365000000000000000000000000000000000000000000000000" }
I get the above error msg when run the depositTokens function of Staking.sol in remix, did i miss any step? thanks.
Gas estimation errored with the following message (see below). The transaction execution will likely fail. Do you want to force sending? Internal JSON-RPC error. { "code": 3, "message": "execution reverted: ERC20: transfer amount exceeds allowance", "data": "0x08c379a00000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002845524332303a207472616e7366657220616d6f756e74206578636565647320616c6c6f77616e6365000000000000000000000000000000000000000000000000" }
I get the above error msg when run the depositTokens function of Staking.sol in remix, did i miss any step? thanks.
It sounds like you need to increase the amount you're approving.
Are you calling .approve
?
If yes, try increasing it to a crazy high amount.
Thanks for the tutorial. Where does the
address()
method come from in line 27ERC20(whitelistedTokens[symbol]).transferFrom(msg.sender, address(this), amount);
in theStaking.sol
file?