Skip to content

Commit

Permalink
Delegatecall and Token
Browse files Browse the repository at this point in the history
  • Loading branch information
RohanNero committed Jan 12, 2024
1 parent 96807d5 commit bc07015
Show file tree
Hide file tree
Showing 39 changed files with 2,385 additions and 60 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,5 @@ node_modules
.eslintcache
.vscode/**
.DS_Store

NOTES.md
11 changes: 11 additions & 0 deletions packages/hardhat/contracts/EIPs/Delegatecall/AdditionContract.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
//SPDX-License-Identifier: MIT

pragma solidity ^0.8.7;

contract AdditionContract {
uint public x;
fallback() external {
uint input = abi.decode(msg.data, (uint));
x = x + input;
}
}
13 changes: 13 additions & 0 deletions packages/hardhat/contracts/EIPs/Delegatecall/Delegatecall.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
//SPDX-License-Identifier: MIT

pragma solidity ^0.8.7;

contract Delegatecall {

uint public x;

function delegate(address y, uint z) public returns(uint) {
y.delegatecall(abi.encode(z));
return x;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
//SPDX-License-Identifier: MIT

pragma solidity ^0.8.7;

contract MultiplicationContract {
uint public x;
fallback() external {
uint input = abi.decode(msg.data, (uint));
x = x * input;
}
}
10 changes: 10 additions & 0 deletions packages/hardhat/contracts/EIPs/Delegatecall/ResetContract.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
//SPDX-License-Identifier: MIT

pragma solidity ^0.8.7;

contract ResetContract {
uint public x;
fallback() external {
x = 0;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
//SPDX-License-Identifier: MIT

pragma solidity ^0.8.7;

contract SubtractionContract {
uint public x;
fallback() external {
uint input = abi.decode(msg.data, (uint));
x = x - input;
}
}
26 changes: 26 additions & 0 deletions packages/hardhat/contracts/EIPs/Token/SimpleSwap.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
//SPDX-License-Identifier: MIT

pragma solidity ^0.8.7;

// import "../../../node_modules/@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";

/**@notice The purpose of this contract is to allow users to test ERC 20's approve -> transferFrom flow
*@dev The one function allows users to swap their Silver token for Gold
*@dev I wanted the price to be based on today's (2024/1/9) gold/silver ratio of ~88
*@dev But 1:10 will suffice for learning purposes s*/
contract SimpleSwap is ERC20 {

address public silverContract;

constructor(address _silverContract) ERC20("Gold", "GLD") {
silverContract = _silverContract;
}

/**@notice Swaps `amount` of Silver token for 1/10th of the amount of Gold */
function swap(uint amount) public returns (uint) {
ERC20(silverContract).transferFrom(msg.sender, address(this), amount);
_mint(msg.sender, amount / 10);
return amount / 10;
}
}
51 changes: 51 additions & 0 deletions packages/hardhat/contracts/EIPs/Token/Token.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.7;

contract Token {
uint public totalSupply;
mapping(address => uint) public balanceOf;
mapping(address => mapping(address => uint)) public allowance;
string public name = "Silver";
string public symbol = "SLV";
uint8 public decimals = 18;

event Transfer(address from, address to, uint amount);
event Approval(address owner, address spender, uint amount);

function transfer(address recipient, uint amount) external returns (bool) {
balanceOf[msg.sender] -= amount;
balanceOf[recipient] += amount;
emit Transfer(msg.sender, recipient, amount);
return true;
}

function approve(address spender, uint amount) external returns (bool) {
allowance[msg.sender][spender] = amount;
emit Approval(msg.sender, spender, amount);
return true;
}

function transferFrom(
address sender,
address recipient,
uint amount
) external returns (bool) {
allowance[sender][msg.sender] -= amount;
balanceOf[sender] -= amount;
balanceOf[recipient] += amount;
emit Transfer(sender, recipient, amount);
return true;
}

function mint(uint amount) external {
balanceOf[msg.sender] += amount;
totalSupply += amount;
emit Transfer(address(0), msg.sender, amount);
}

function burn(uint amount) external {
balanceOf[msg.sender] -= amount;
totalSupply -= amount;
emit Transfer(msg.sender, address(0), amount);
}
}
97 changes: 97 additions & 0 deletions packages/hardhat/deploy/01_eip_delegatecall.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
import { HardhatRuntimeEnvironment } from "hardhat/types";
import { DeployFunction } from "hardhat-deploy/types";

/**
* Deploys the EIP contracts
* constructor arguments set to the deployer address
*
* @param hre HardhatRuntimeEnvironment object.
*/
const deployEIPs: DeployFunction = async function (hre: HardhatRuntimeEnvironment) {
/*
On localhost, the deployer account is the one that comes with Hardhat, which is already funded.
When deploying to live networks (e.g `yarn deploy --network goerli`), the deployer account
should have sufficient balance to pay for the gas fees for contract creation.
You can generate a random account with `yarn generate` which will fill DEPLOYER_PRIVATE_KEY
with a random private key in the .env file (then used on hardhat.config.ts)
You can run the `yarn account` command to check your balance in every network.
*/
const { deployer } = await hre.getNamedAccounts();
const { deploy } = hre.deployments;

/** Delegatecall - EIP 7 */
const delegatecall = await deploy("Delegatecall", {
from: deployer,
log: true,
// autoMine: can be passed to the deploy function to make the deployment process faster on local networks by
// automatically mining the contract deployment transaction. There is no effect on live networks.
autoMine: true,
waitConfirmations: 5,
});

const add = await deploy("AdditionContract", {
from: deployer,
log: true,
autoMine: true,
waitConfirmations: 5,
});

const sub = await deploy("SubtractionContract", {
from: deployer,
log: true,
autoMine: true,
waitConfirmations: 5,
});

const mul = await deploy("MultiplicationContract", {
from: deployer,
log: true,
autoMine: true,
waitConfirmations: 5,
});

const reset = await deploy("ResetContract", {
from: deployer,
log: true,
autoMine: true,
waitConfirmations: 5,
});

const contractsToVerify = [
{ address: delegatecall.address, contract: "contracts/Delegatecall/Delegatecall.sol:Delegatecall" },
{ address: add.address, contract: "contracts/Delegatecall/Delegatecall.sol:AdditionContract" },
{ address: sub.address, contract: "contracts/Delegatecall/Delegatecall.sol:SubtractionContract" },
{ address: mul.address, contract: "contracts/Delegatecall/Delegatecall.sol:MultiplicationContract" },
{ address: reset.address, contract: "contracts/Delegatecall/Delegatecall.sol:ResetContract" },
];

for (const contract of contractsToVerify) {
try {
console.log(`Verifying contract at address ${contract.address}...`);
console.log("contract:", contract);
await hre.run("verify:verify", {
address: contract.address,
contract: contract.contract,
});
} catch (error) {
if (error.message.includes("already verifie")) {
console.log(`Contract at address ${contract.address} already verified!`);
} else if (error.message.includes("recently deployed")) {
console.error(`Contract bytecode not available yet, try again in a minute!`);
} else {
console.error(`Error verifying contract at address ${contract.address}:`, error);
}
}
}

// Get the deployed contract
// const yourContract = await hre.ethers.getContract("YourContract", deployer);
};

export default deployEIPs;

// Tags are useful if you have multiple deploy files and only want to run one of them.
// e.g. yarn deploy --tags eip
deployEIPs.tags = ["eip", "delegatecall", "7"];
84 changes: 84 additions & 0 deletions packages/hardhat/deploy/02_eip_token.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
import { HardhatRuntimeEnvironment } from "hardhat/types";
import { DeployFunction } from "hardhat-deploy/types";

/**
* Deploys the EIP contracts
* constructor arguments set to the deployer address
*
* @param hre HardhatRuntimeEnvironment object.
*/
const deployEIPs: DeployFunction = async function (hre: HardhatRuntimeEnvironment) {
/*
On localhost, the deployer account is the one that comes with Hardhat, which is already funded.
When deploying to live networks (e.g `yarn deploy --network goerli`), the deployer account
should have sufficient balance to pay for the gas fees for contract creation.
You can generate a random account with `yarn generate` which will fill DEPLOYER_PRIVATE_KEY
with a random private key in the .env file (then used on hardhat.config.ts)
You can run the `yarn account` command to check your balance in every network.
*/
const { deployer } = await hre.getNamedAccounts();
const { deploy } = hre.deployments;

/** Token - EIP 20 Silver */
const token = await deploy("Token", {
from: deployer,
log: true,
// autoMine: can be passed to the deploy function to make the deployment process faster on local networks by
// automatically mining the contract deployment transaction. There is no effect on live networks.
autoMine: true,
waitConfirmations: 5,
});

/** Simple Swap - EIP 20 Gold */
const swap = await deploy("SimpleSwap", {
from: deployer,
log: true,
args: [token.address],
// autoMine: can be passed to the deploy function to make the deployment process faster on local networks by
// automatically mining the contract deployment transaction. There is no effect on live networks.
autoMine: true,
waitConfirmations: 5,
});

// Verify Token
try {
console.log(`Verifying contract at address ${token.address}...`);
await hre.run("verify:verify", {
address: token.address,
contract: "contracts/EIPs/Token/Token.sol:Token",
});
} catch (error: any) {
if (error.message.includes("already verified")) {
console.log(`Contract at address ${token.address} already verified!`);
} else if (error.message.includes("recently deployed")) {
console.error(`Contract bytecode not available yet, try again in a minute!`);
} else {
console.error(`Error verifying contract at address ${token.address}:`, error);
}
}
// Verify Simple Swap
try {
console.log(`Verifying contract at address ${swap.address}...`);
await hre.run("verify:verify", {
address: swap.address,
constructorArguments: [token.address],
contract: "contracts/EIPs/Token/SimpleSwap.sol:SimpleSwap",
});
} catch (error: any) {
if (error.message.includes("already verified")) {
console.log(`Contract at address ${token.address} already verified!`);
} else if (error.message.includes("recently deployed")) {
console.error(`Contract bytecode not available yet, try again in a minute!`);
} else {
console.error(`Error verifying contract at address ${token.address}:`, error);
}
}
};

export default deployEIPs;

// Tags are useful if you have multiple deploy files and only want to run one of them.
// e.g. yarn deploy --tags eip
deployEIPs.tags = ["eip", "token", "20"];
13 changes: 10 additions & 3 deletions packages/hardhat/hardhat.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ const deployerPrivateKey =
process.env.DEPLOYER_PRIVATE_KEY ?? "0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80";
// If not set, it uses ours Etherscan default API key.
const etherscanApiKey = process.env.ETHERSCAN_API_KEY || "DNXJA8RX2Q3VZ4URQIWP7Z68CJXQZSC6AW";
const polyscanApiKey = process.env.POLYSCAN_API_KEY || "DNXJA8RX2Q3VZ4URQIWP7Z68CJXQZSC6AW";

const config: HardhatUserConfig = {
solidity: {
Expand Down Expand Up @@ -131,9 +132,15 @@ const config: HardhatUserConfig = {
accounts: [deployerPrivateKey],
},
},
verify: {
etherscan: {
apiKey: `${etherscanApiKey}`,
etherscan: {
apiKey: {
polygon: `${polyscanApiKey}`,
polygonMumbai: `${polyscanApiKey}`,
mainnet: `${etherscanApiKey}`,
goerli: `${etherscanApiKey}`,
sepolia: `${etherscanApiKey}`,
avalancheFuji: "snowtrace",
avalanche: `${etherscanApiKey}`,
},
},
};
Expand Down
1 change: 1 addition & 0 deletions packages/nextjs/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ yarn-error.log*
.env.development.local
.env.test.local
.env.production.local
.env

# vercel
.vercel
Expand Down
Loading

0 comments on commit bc07015

Please sign in to comment.