diff --git a/ethereum/fly/app/src/js/components/Form/Form.tsx b/ethereum/fly/app/src/js/components/Form/Form.tsx index 59d266e..b6a509b 100644 --- a/ethereum/fly/app/src/js/components/Form/Form.tsx +++ b/ethereum/fly/app/src/js/components/Form/Form.tsx @@ -8,6 +8,7 @@ import ChangeOwnerForm from './ChangeOwner/ChangeOwnerForm'; import Balance from './Balance'; import TransferForm from './Transfer/TransferForm'; import RenounceOwnershipForm from './RenounceOwnership/RenounceOwnershipForm'; +import SwappedSupply from './SwappedSupply'; const Form = () => { const { status } = useMetaMask(); @@ -16,6 +17,7 @@ const Form = () => { status === 'connected' ? ( + diff --git a/ethereum/fly/app/src/js/components/Form/SwappedSupply.tsx b/ethereum/fly/app/src/js/components/Form/SwappedSupply.tsx new file mode 100644 index 0000000..ca89792 --- /dev/null +++ b/ethereum/fly/app/src/js/components/Form/SwappedSupply.tsx @@ -0,0 +1,28 @@ +import * as React from 'react'; +import { useConnectedMetaMask, useMetaMask } from 'metamask-react'; +import Web3Client from '../../web3/Web3Client'; +import Container from '../reusable/Container'; +import Heading from '../reusable/Heading'; +import { ChainId } from '../MetamaskConnect'; + +const SwappedSupply = () => { + const { account, ethereum, chainId } = useConnectedMetaMask(); + const [swappedSupply, setSwappedSupply] = React.useState(0); + + React.useEffect(() => { + const client = new Web3Client(account, ethereum, chainId as ChainId); + client.swappedSupply().then((supply) => { + setSwappedSupply(supply); + }); + }); + + return ( + + + Total circulating supply (swapped): {swappedSupply} + + + ); +}; + +export default SwappedSupply; diff --git a/ethereum/fly/app/src/js/web3/Web3Client.ts b/ethereum/fly/app/src/js/web3/Web3Client.ts index 434e2e4..14fe95a 100644 --- a/ethereum/fly/app/src/js/web3/Web3Client.ts +++ b/ethereum/fly/app/src/js/web3/Web3Client.ts @@ -1,6 +1,6 @@ import Web3 from 'web3'; -import { ABI, CONTRACT_ADDRESS } from './contracts/MyToken'; +import { ABI, CONTRACT_ADDRESS } from './contracts/Fly'; import { ChainId } from '../components/MetamaskConnect'; export default class Web3Client { @@ -38,6 +38,11 @@ export default class Web3Client { return contract.methods.balanceOf(address).call(); } + async swappedSupply(): Promise { + const contract = this.getContract(); + return contract.methods.swappedSupply().call(); + } + private getContract() { return new this.web3.eth.Contract(ABI, CONTRACT_ADDRESS[this.chainId]); } diff --git a/ethereum/fly/app/src/js/web3/contracts/MyToken.ts b/ethereum/fly/app/src/js/web3/contracts/Fly.ts similarity index 78% rename from ethereum/fly/app/src/js/web3/contracts/MyToken.ts rename to ethereum/fly/app/src/js/web3/contracts/Fly.ts index e334928..07fa729 100644 --- a/ethereum/fly/app/src/js/web3/contracts/MyToken.ts +++ b/ethereum/fly/app/src/js/web3/contracts/Fly.ts @@ -4,30 +4,20 @@ export const ABI = [ { inputs: [ { - internalType: 'string', - name: 'name', - type: 'string', - }, - { - internalType: 'string', - name: 'symbol', - type: 'string', + internalType: 'address', + name: '_initialOwner', + type: 'address', }, { internalType: 'address', - name: 'initialOwner', + name: '_fly_canister_address', type: 'address', }, { internalType: 'uint256', - name: 'initialSupply', + name: '_swapFee', type: 'uint256', }, - { - internalType: 'uint8', - name: 'decs', - type: 'uint8', - }, ], stateMutability: 'nonpayable', type: 'constructor', @@ -165,6 +155,31 @@ export const ABI = [ name: 'Approval', type: 'event', }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: '_from', + type: 'address', + }, + { + indexed: true, + internalType: 'bytes32', + name: '_principal', + type: 'bytes32', + }, + { + indexed: false, + internalType: 'uint256', + name: '_amount', + type: 'uint256', + }, + ], + name: 'FlySwapped', + type: 'event', + }, { anonymous: false, inputs: [ @@ -289,6 +304,19 @@ export const ABI = [ stateMutability: 'view', type: 'function', }, + { + inputs: [], + name: 'getFlyCanisterAddress', + outputs: [ + { + internalType: 'address', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, { inputs: [], name: 'name', @@ -322,6 +350,63 @@ export const ABI = [ stateMutability: 'nonpayable', type: 'function', }, + { + inputs: [ + { + internalType: 'uint256', + name: '_swapFee', + type: 'uint256', + }, + ], + name: 'setSwapFee', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'bytes32', + name: '_recipient', + type: 'bytes32', + }, + { + internalType: 'uint256', + name: '_amount', + type: 'uint256', + }, + ], + name: 'swap', + outputs: [], + stateMutability: 'payable', + type: 'function', + }, + { + inputs: [], + name: 'swapFee', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'swappedSupply', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, { inputs: [], name: 'symbol', @@ -348,6 +433,24 @@ export const ABI = [ stateMutability: 'view', type: 'function', }, + { + inputs: [ + { + internalType: 'address', + name: '_recipient', + type: 'address', + }, + { + internalType: 'uint256', + name: '_amount', + type: 'uint256', + }, + ], + name: 'transcribeSwap', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, { inputs: [ { diff --git a/ethereum/fly/contracts/Fly.sol b/ethereum/fly/contracts/Fly.sol index bf381a0..66190f7 100644 --- a/ethereum/fly/contracts/Fly.sol +++ b/ethereum/fly/contracts/Fly.sol @@ -40,6 +40,18 @@ contract Fly is ERC20, Ownable { return _decimals; } + function totalSupply() public view virtual override returns (uint256) { + return 8_880_101_010_000_000_000; + } + + /** + * @dev Returns the total supply of tokens swapped from Ethereum blockchain to IC. Basically it's the circulating supply of the token on Ethereum. + * @return The total supply of tokens swapped from Ethereum blockchain to IC. + */ + function swappedSupply() public view returns (uint256) { + return ERC20.totalSupply(); + } + /** * @dev Returns the address of the fly canister. * @return The address of the fly canister. diff --git a/ethereum/fly/test/Fly.ts b/ethereum/fly/test/Fly.ts index 6a6a919..0baab59 100644 --- a/ethereum/fly/test/Fly.ts +++ b/ethereum/fly/test/Fly.ts @@ -3,7 +3,7 @@ import { ethers } from "hardhat"; import { Fly } from "../typechain-types"; import { SignerWithAddress } from "@nomiclabs/hardhat-ethers/signers"; -// const INITIAL_SUPPLY = "8880101010000000000"; // 8 milions +const TOTAL_SUPPLY = "8880101010000000000"; // 8 milions const NAME = "Fly"; const SYMBOL = "FLY"; const DECIMALS = 12; @@ -119,6 +119,14 @@ describe("Fly", () => { expect(await token.balanceOf(owner.address)).to.equal(750); }); + it("should get total supply and swapped supply", async () => { + const { flyCanister, owner, token } = deploy; + await token.transcribeSwap(owner.address, 1_000); + + expect(await token.totalSupply()).to.equal(TOTAL_SUPPLY); + expect(await token.swappedSupply()).to.equal(1_000); + }); + it("Should update swap fee", async () => { const { token } = deploy; await token.setSwapFee(200);