diff --git a/ethereum/fly/.env.github b/ethereum/fly/.env.github index e8713ec..bd646c7 100644 --- a/ethereum/fly/.env.github +++ b/ethereum/fly/.env.github @@ -4,5 +4,4 @@ PROD_PRIVATE_KEY="00000000000000000000000000000000000000000000000000000000000000 DEV_PRIVATE_KEY="0000000000000000000000000000000000000000000000000000000000000000" LOCAL_PRIVATE_KEY="ac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80" OWNER_ADDRESS="0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266" -SWAP_FEE=10 ETHERSCAN_API_KEY=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx diff --git a/ethereum/fly/app/src/js/components/Form/Form.tsx b/ethereum/fly/app/src/js/components/Form/Form.tsx index d43f36b..bb56f6f 100644 --- a/ethereum/fly/app/src/js/components/Form/Form.tsx +++ b/ethereum/fly/app/src/js/components/Form/Form.tsx @@ -13,7 +13,6 @@ import MintTestnetTokens from './MintTestnetTokens/MintTestnetTokens'; import SetFlyCanisterAddressForm from './SetFlyCanisterAddress/SetFlyCanisterAddressForm'; import Web3Client from '../../web3/Web3Client'; import { ChainId } from '../MetamaskConnect'; -import SwapFeeForm from './SwapFee/SwapFeeForm'; const Form = () => { const { status, account, ethereum, chainId } = useMetaMask(); @@ -46,9 +45,6 @@ const Form = () => { - - - diff --git a/ethereum/fly/app/src/js/components/Form/SwapFee/SwapFeeForm.tsx b/ethereum/fly/app/src/js/components/Form/SwapFee/SwapFeeForm.tsx deleted file mode 100644 index 0e99c4a..0000000 --- a/ethereum/fly/app/src/js/components/Form/SwapFee/SwapFeeForm.tsx +++ /dev/null @@ -1,91 +0,0 @@ -import * as React from 'react'; -import { useConnectedMetaMask } from 'metamask-react'; - -import Container from '../../reusable/Container'; -import Heading from '../../reusable/Heading'; -import Input from '../../reusable/Input'; -import Button from '../../reusable/Button'; -import Web3Client from '../../../web3/Web3Client'; -import Alerts from '../../reusable/Alerts'; -import { ChainId } from '../../MetamaskConnect'; - -const SwapFeeForm = () => { - const { account, ethereum, chainId } = useConnectedMetaMask(); - const [fee, setFee] = React.useState(''); - const [currentFee, setCurrentFee] = React.useState(); - const [pendingTx, setPendingTx] = React.useState(false); - const [error, setError] = React.useState(); - - const onFeeChanged = (event: React.ChangeEvent) => { - setFee(event.target.value); - }; - - const onChangeFee = () => { - setPendingTx(true); - const client = new Web3Client(account, ethereum, chainId as ChainId); - - const feeNum = Number(fee); - - client - .setSwapFee(feeNum) - .then(() => { - setPendingTx(false); - setError(undefined); - }) - .catch((e) => { - setError(e.message); - setPendingTx(false); - }); - }; - - React.useEffect(() => { - if (!account || !ethereum || !chainId) { - return; - } - - const client = new Web3Client(account, ethereum, chainId as ChainId); - client - .swapFee() - .then((currFee) => { - setCurrentFee(Number(currFee)); - }) - .catch((e) => { - setError(e.message); - }); - }, [account, ethereum, chainId]); - - const btnDisabled = !isAmountNumber(fee) || pendingTx; - - return ( - - Swap Fee - Current Swap Fee: {currentFee} - - - Change swap fee - - {error && ( - -

{error}

-
- )} -
- ); -}; - -const isAmountNumber = (amount: string) => { - const amountNum = Number(amount); - return !isNaN(amountNum); -}; - -export default SwapFeeForm; diff --git a/ethereum/fly/app/src/js/web3/Web3Client.ts b/ethereum/fly/app/src/js/web3/Web3Client.ts index 8fa4eb6..9df50bc 100644 --- a/ethereum/fly/app/src/js/web3/Web3Client.ts +++ b/ethereum/fly/app/src/js/web3/Web3Client.ts @@ -67,16 +67,6 @@ export default class Web3Client { return contract.methods.swappedSupply().call(); } - async swapFee(): Promise { - const contract = this.getContract(); - return contract.methods.swapFee().call(); - } - - async setSwapFee(fee: number) { - const contract = this.getContract(); - return contract.methods.setSwapFee(fee).send({ from: this.address }); - } - private getContract() { return new this.web3.eth.Contract(ABI, CONTRACT_ADDRESS[this.chainId]); } diff --git a/ethereum/fly/app/src/js/web3/contracts/Fly.ts b/ethereum/fly/app/src/js/web3/contracts/Fly.ts index ab144f9..0f5068f 100644 --- a/ethereum/fly/app/src/js/web3/contracts/Fly.ts +++ b/ethereum/fly/app/src/js/web3/contracts/Fly.ts @@ -8,11 +8,6 @@ export const ABI = [ name: '_initialOwner', type: 'address', }, - { - internalType: 'uint256', - name: '_swapFee', - type: 'uint256', - }, ], stateMutability: 'nonpayable', type: 'constructor', @@ -376,19 +371,6 @@ export const ABI = [ stateMutability: 'nonpayable', type: 'function', }, - { - inputs: [ - { - internalType: 'uint256', - name: '_swapFee', - type: 'uint256', - }, - ], - name: 'setSwapFee', - outputs: [], - stateMutability: 'nonpayable', - type: 'function', - }, { inputs: [ { @@ -404,20 +386,7 @@ export const ABI = [ ], name: 'swap', outputs: [], - stateMutability: 'payable', - type: 'function', - }, - { - inputs: [], - name: 'swapFee', - outputs: [ - { - internalType: 'uint256', - name: '', - type: 'uint256', - }, - ], - stateMutability: 'view', + stateMutability: 'nonpayable', type: 'function', }, { diff --git a/ethereum/fly/contracts/Fly.sol b/ethereum/fly/contracts/Fly.sol index a274cda..56b575f 100644 --- a/ethereum/fly/contracts/Fly.sol +++ b/ethereum/fly/contracts/Fly.sol @@ -10,7 +10,6 @@ import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol"; contract Fly is ERC20, Ownable { address private fly_canister_address; uint8 private _decimals; - uint256 public swapFee; uint256 private constant GOERLI_CHAIN_ID = 5; uint256 private constant HARDHAT_CHAIN_ID = 31337; @@ -22,11 +21,9 @@ contract Fly is ERC20, Ownable { ); constructor( - address _initialOwner, - uint256 _swapFee + address _initialOwner ) ERC20("Fly", "FLY") Ownable(_initialOwner) { _decimals = 12; - swapFee = _swapFee; fly_canister_address = address(0); } @@ -99,20 +96,12 @@ contract Fly is ERC20, Ownable { fly_canister_address = _fly_canister_address; } - /** - * @dev Sets the swap fee. - * @param _swapFee The new swap fee. - */ - function setSwapFee(uint256 _swapFee) public isOwnerOrFlyCanister { - swapFee = _swapFee; - } - /** * @dev Swaps the Fly tokens from Ethereum blockchain to IC from the caller to the recipient principal for the provided amount. * @param _recipient The principal to receive the tokens. * @param _amount The amount of tokens to swap. */ - function swap(bytes32 _recipient, uint256 _amount) public payable { + function swap(bytes32 _recipient, uint256 _amount) public { // check if the fly canister address is set require( fly_canister_address != address(0), @@ -123,17 +112,10 @@ contract Fly is ERC20, Ownable { balanceOf(msg.sender) >= _amount, "Fly: caller does not have enough tokens to swap" ); - // check if the caller has enough ether to pay the fee - require( - msg.value >= swapFee, - "Fly: caller does not have enough ether to pay the fee" - ); // burn the tokens from the caller _burn(msg.sender, _amount); // emit swap event emit FlySwapped(msg.sender, _recipient, _amount); - // pay fee - payable(fly_canister_address).transfer(msg.value); } /** diff --git a/ethereum/fly/scripts/deploy.ts b/ethereum/fly/scripts/deploy.ts index f9800eb..dbab36e 100644 --- a/ethereum/fly/scripts/deploy.ts +++ b/ethereum/fly/scripts/deploy.ts @@ -1,12 +1,12 @@ import { ethers } from "hardhat"; require("dotenv").config(); -const { OWNER_ADDRESS, SWAP_FEE } = process.env; +const { OWNER_ADDRESS } = process.env; async function main() { // deploy contract const Contract = await ethers.getContractFactory("Fly"); - const contract = await Contract.deploy(OWNER_ADDRESS!, SWAP_FEE!); + const contract = await Contract.deploy(OWNER_ADDRESS!); await contract.waitForDeployment(); const address = await contract.getAddress(); console.log(`Contract deployed to ${address}`); diff --git a/ethereum/fly/test/Fly.ts b/ethereum/fly/test/Fly.ts index b4c0d48..ae53e55 100644 --- a/ethereum/fly/test/Fly.ts +++ b/ethereum/fly/test/Fly.ts @@ -7,7 +7,6 @@ const TOTAL_SUPPLY = "8880101010000000000"; // 8 milions const NAME = "Fly"; const SYMBOL = "FLY"; const DECIMALS = 12; -const INITIAL_FEE = 100; const DUMMY_PRINCIPAL = new Uint8Array([ 64, 123, 39, 130, 111, 49, 3, 65, 143, 8, 40, 152, 37, 163, 102, 10, 226, 6, 132, 148, 181, 23, 75, 76, 77, 109, 126, 107, 2, 14, 0, 10, @@ -27,7 +26,7 @@ describe("Fly", () => { const signer = await ethers.provider.getSigner(owner.address); const Contract = await ethers.getContractFactory("Fly"); - const contract = await Contract.deploy(owner.address, INITIAL_FEE); + const contract = await Contract.deploy(owner.address); await contract.waitForDeployment(); const address = await contract.getAddress(); @@ -45,7 +44,6 @@ describe("Fly", () => { expect(await token.name()).to.equal(NAME); expect(await token.symbol()).to.equal(SYMBOL); expect(await token.decimals()).to.equal(DECIMALS); - expect(await token.swapFee()).to.equal(INITIAL_FEE); // check balance expect(await token.balanceOf(owner.address)).to.equal(0); // check fly canister is unset @@ -73,7 +71,6 @@ describe("Fly", () => { it("Should swap 100 tokens", async () => { const { token, owner, flyCanister } = deploy; await token.mintTestnetTokens(owner.address, 100); - const fee = await token.swapFee(); await token.setFlyCanisterAddress(flyCanister.address); const initialFlyCanisterBalance = await ethers.provider.getBalance( @@ -83,52 +80,19 @@ describe("Fly", () => { const initialBalance = await ethers.provider.getBalance(owner.address); // swap and check event is emitted - await expect( - token.swap(DUMMY_PRINCIPAL, 75, { - value: fee, - }) - ) + await expect(token.swap(DUMMY_PRINCIPAL, 75)) .to.emit(token, "FlySwapped") .withArgs(owner.address, DUMMY_PRINCIPAL, 75); expect(await token.balanceOf(owner.address)).to.equal(25); - - // check owner has paid FEE ethers - const finalBalance = - initialBalance - (await ethers.provider.getBalance(owner.address)); - expect(finalBalance).to.greaterThan(fee); - - // check fly canister has received the swap fee - const expectedFlyCanisterBalance = initialFlyCanisterBalance + fee; - expect(await ethers.provider.getBalance(flyCanister.address)).to.equal( - expectedFlyCanisterBalance - ); }); it("should fail swap if fly canister address is not set", async () => { const { token, owner } = deploy; await token.mintTestnetTokens(owner.address, 100); - const fee = await token.swapFee(); - - expect( - token.swap(DUMMY_PRINCIPAL, 75, { - value: fee, - }) - ).to.be.revertedWith("Fly: fly canister address not set"); - }); - - it("should fail swap if fee is not paid", async () => { - const { token, owner, flyCanister } = deploy; - await token.setFlyCanisterAddress(flyCanister.address); - await token.mintTestnetTokens(owner.address, 100); - - await expect( - token.swap(DUMMY_PRINCIPAL, 75, { - value: 10, - }) - ).to.be.revertedWith( - "Fly: caller does not have enough ether to pay the fee" + expect(token.swap(DUMMY_PRINCIPAL, 75)).to.be.revertedWith( + "Fly: fly canister address not set" ); }); @@ -136,13 +100,10 @@ describe("Fly", () => { const { token, owner, flyCanister } = deploy; await token.setFlyCanisterAddress(flyCanister.address); await token.mintTestnetTokens(owner.address, 100); - const fee = await token.swapFee(); - await expect( - token.swap(DUMMY_PRINCIPAL, 101, { - value: fee, - }) - ).to.be.revertedWith("Fly: caller does not have enough tokens to swap"); + await expect(token.swap(DUMMY_PRINCIPAL, 101)).to.be.revertedWith( + "Fly: caller does not have enough tokens to swap" + ); }); it("Should transfer 500 tokens", async () => { @@ -162,47 +123,6 @@ describe("Fly", () => { expect(await token.swappedSupply()).to.equal(1_000); }); - it("Should update swap fee if owner", async () => { - const { token } = deploy; - await token.setSwapFee(200); - expect(await token.swapFee()).to.equal(200); - }); - - it("Should update swap fee if fly canister", async () => { - const { token, owner, flyCanister } = deploy; - // set fly canister address to owner - await token.setFlyCanisterAddress(owner.address); - // transfer ownership to fly canister - await token.transferOwnership(flyCanister.address); - // update fee - await token.setSwapFee(200); - expect(await token.swapFee()).to.equal(200); - }); - - it("Should fail to set swap fee if not owner or fly canister", async () => { - const { token, flyCanister } = deploy; - // set fly canister address to owner - await token.setFlyCanisterAddress(flyCanister.address); - // transfer ownership to fly canister - await token.transferOwnership(flyCanister.address); - // update fee - await expect(token.setSwapFee(200)).to.be.revertedWith( - "Fly: caller is not the fly canister nor the owner" - ); - expect(await token.swapFee()).to.equal(INITIAL_FEE); - }); - - it("Should fail to set swap fee if not owner and fly canister is unset", async () => { - const { token, flyCanister } = deploy; - // transfer ownership to fly canister - await token.transferOwnership(flyCanister.address); - // update fee - await expect(token.setSwapFee(200)).to.be.revertedWith( - "Fly: caller is not the fly canister nor the owner" - ); - expect(await token.swapFee()).to.equal(INITIAL_FEE); - }); - it("should renounce ownership", async () => { const { token } = deploy; await token.renounceOwnership();