mirror of
https://github.com/Instadapp/infinite-proxy.git
synced 2024-07-29 21:47:49 +00:00
commit
cecc43aa95
12
contracts/example/common/variables.sol
Normal file
12
contracts/example/common/variables.sol
Normal file
|
|
@ -0,0 +1,12 @@
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
pragma solidity ^0.8.0;
|
||||||
|
|
||||||
|
contract Constants {
|
||||||
|
// token supported
|
||||||
|
address public constant token = 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48; // USDC
|
||||||
|
}
|
||||||
|
|
||||||
|
contract Variables is Constants {
|
||||||
|
// userAddress => amount deposited
|
||||||
|
mapping(address => uint256) internal _userBalance;
|
||||||
|
}
|
||||||
26
contracts/example/dummyImplementation.sol
Normal file
26
contracts/example/dummyImplementation.sol
Normal file
|
|
@ -0,0 +1,26 @@
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
pragma solidity ^0.8.0;
|
||||||
|
|
||||||
|
contract UserModule {
|
||||||
|
/**
|
||||||
|
* @dev User function to supply.
|
||||||
|
* @param amount_ amount to supply.
|
||||||
|
*/
|
||||||
|
function supply(uint256 amount_) external {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dev User function to withdraw.
|
||||||
|
* @param amount_ amount to withdraw.
|
||||||
|
*/
|
||||||
|
function withdraw(uint256 amount_) external {}
|
||||||
|
}
|
||||||
|
|
||||||
|
contract ReadModule {
|
||||||
|
/**
|
||||||
|
* @dev Read function to get user's balance in the contract.
|
||||||
|
* @param user_ address of user.
|
||||||
|
*/
|
||||||
|
function userBalance(address user_) public view returns (uint256) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
contract DummyImplementation is UserModule, ReadModule {}
|
||||||
10
contracts/example/module1/events.sol
Normal file
10
contracts/example/module1/events.sol
Normal file
|
|
@ -0,0 +1,10 @@
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
pragma solidity ^0.8.0;
|
||||||
|
|
||||||
|
import "../common/variables.sol";
|
||||||
|
|
||||||
|
contract Events is Variables {
|
||||||
|
event supplyLog(uint256 amount_);
|
||||||
|
|
||||||
|
event withdrawLog(uint256 amount_);
|
||||||
|
}
|
||||||
32
contracts/example/module1/main.sol
Normal file
32
contracts/example/module1/main.sol
Normal file
|
|
@ -0,0 +1,32 @@
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
pragma solidity ^0.8.0;
|
||||||
|
|
||||||
|
import "./events.sol";
|
||||||
|
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
|
||||||
|
import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
|
||||||
|
|
||||||
|
contract UserModule is Events {
|
||||||
|
using SafeERC20 for IERC20;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dev User function to supply.
|
||||||
|
* @param amount_ amount to supply.
|
||||||
|
*/
|
||||||
|
function supply(uint256 amount_) external {
|
||||||
|
IERC20(token).safeTransferFrom(msg.sender, address(this), amount_);
|
||||||
|
_userBalance[msg.sender] += amount_;
|
||||||
|
|
||||||
|
emit supplyLog(amount_);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dev User function to withdraw.
|
||||||
|
* @param amount_ amount to withdraw.
|
||||||
|
*/
|
||||||
|
function withdraw(uint256 amount_) external {
|
||||||
|
_userBalance[msg.sender] -= amount_;
|
||||||
|
IERC20(token).safeTransfer(msg.sender, amount_);
|
||||||
|
|
||||||
|
event withdrawLog(uint256 amount_);
|
||||||
|
}
|
||||||
|
}
|
||||||
14
contracts/example/module2/main.sol
Normal file
14
contracts/example/module2/main.sol
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
pragma solidity ^0.8.0;
|
||||||
|
|
||||||
|
import "../common/variables.sol";
|
||||||
|
|
||||||
|
contract ReadModule is Variables {
|
||||||
|
/**
|
||||||
|
* @dev Read function to get user's balance in the contract.
|
||||||
|
* @param user_ address of user.
|
||||||
|
*/
|
||||||
|
function userBalance(address user_) public view returns (uint256) {
|
||||||
|
return _userBalance[user_];
|
||||||
|
}
|
||||||
|
}
|
||||||
10
contracts/example/proxy.sol
Normal file
10
contracts/example/proxy.sol
Normal file
|
|
@ -0,0 +1,10 @@
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
pragma solidity ^0.8.0;
|
||||||
|
|
||||||
|
import "../infiniteProxy/proxy.sol";
|
||||||
|
|
||||||
|
contract Example is Proxy {
|
||||||
|
constructor(address admin_, address dummyImplementation_)
|
||||||
|
Proxy(admin_, dummyImplementation_)
|
||||||
|
{}
|
||||||
|
}
|
||||||
13
package-lock.json
generated
13
package-lock.json
generated
|
|
@ -8,6 +8,9 @@
|
||||||
"name": "infinite-proxy",
|
"name": "infinite-proxy",
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
|
"dependencies": {
|
||||||
|
"@openzeppelin/contracts": "^4.5.0"
|
||||||
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@nomiclabs/hardhat-ethers": "^2.0.5",
|
"@nomiclabs/hardhat-ethers": "^2.0.5",
|
||||||
"@nomiclabs/hardhat-etherscan": "^3.0.3",
|
"@nomiclabs/hardhat-etherscan": "^3.0.3",
|
||||||
|
|
@ -1497,6 +1500,11 @@
|
||||||
"hardhat": "^2.0.0"
|
"hardhat": "^2.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@openzeppelin/contracts": {
|
||||||
|
"version": "4.5.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@openzeppelin/contracts/-/contracts-4.5.0.tgz",
|
||||||
|
"integrity": "sha512-fdkzKPYMjrRiPK6K4y64e6GzULR7R7RwxSigHS8DDp7aWDeoReqsQI+cxHV1UuhAqX69L1lAaWDxenfP+xiqzA=="
|
||||||
|
},
|
||||||
"node_modules/@resolver-engine/core": {
|
"node_modules/@resolver-engine/core": {
|
||||||
"version": "0.3.3",
|
"version": "0.3.3",
|
||||||
"resolved": "https://registry.npmjs.org/@resolver-engine/core/-/core-0.3.3.tgz",
|
"resolved": "https://registry.npmjs.org/@resolver-engine/core/-/core-0.3.3.tgz",
|
||||||
|
|
@ -24098,6 +24106,11 @@
|
||||||
"@types/web3": "1.0.19"
|
"@types/web3": "1.0.19"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"@openzeppelin/contracts": {
|
||||||
|
"version": "4.5.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@openzeppelin/contracts/-/contracts-4.5.0.tgz",
|
||||||
|
"integrity": "sha512-fdkzKPYMjrRiPK6K4y64e6GzULR7R7RwxSigHS8DDp7aWDeoReqsQI+cxHV1UuhAqX69L1lAaWDxenfP+xiqzA=="
|
||||||
|
},
|
||||||
"@resolver-engine/core": {
|
"@resolver-engine/core": {
|
||||||
"version": "0.3.3",
|
"version": "0.3.3",
|
||||||
"resolved": "https://registry.npmjs.org/@resolver-engine/core/-/core-0.3.3.tgz",
|
"resolved": "https://registry.npmjs.org/@resolver-engine/core/-/core-0.3.3.tgz",
|
||||||
|
|
|
||||||
|
|
@ -47,5 +47,8 @@
|
||||||
"ts-node": "^10.7.0",
|
"ts-node": "^10.7.0",
|
||||||
"typechain": "^5.2.0",
|
"typechain": "^5.2.0",
|
||||||
"typescript": "^4.6.3"
|
"typescript": "^4.6.3"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@openzeppelin/contracts": "^4.5.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,17 @@
|
||||||
// When running the script with `npx hardhat run <script>` you'll find the Hardhat
|
// When running the script with `npx hardhat run <script>` you'll find the Hardhat
|
||||||
// Runtime Environment's members available in the global scope.
|
// Runtime Environment's members available in the global scope.
|
||||||
import { ethers } from "hardhat";
|
import { ethers } from "hardhat";
|
||||||
|
import { Contract } from "ethers";
|
||||||
|
const hre = require("hardhat");
|
||||||
|
|
||||||
|
const UserModuleSigs = [
|
||||||
|
"supply(uint256)",
|
||||||
|
"withdraw(uint256)"
|
||||||
|
].map((a) => ethers.utils.id(a).slice(0, 10));
|
||||||
|
|
||||||
|
const ReadModuleSigs = [
|
||||||
|
"userBalance(address)"
|
||||||
|
].map((a) => ethers.utils.id(a).slice(0, 10));
|
||||||
|
|
||||||
async function main() {
|
async function main() {
|
||||||
// Hardhat always runs the compile task when running scripts with its command
|
// Hardhat always runs the compile task when running scripts with its command
|
||||||
|
|
@ -14,12 +25,97 @@ async function main() {
|
||||||
// await hre.run('compile');
|
// await hre.run('compile');
|
||||||
|
|
||||||
// We get the contract to deploy
|
// We get the contract to deploy
|
||||||
const Greeter = await ethers.getContractFactory("Greeter");
|
let proxy: Contract,
|
||||||
const greeter = await Greeter.deploy("Hello, Hardhat!");
|
userModule: Contract,
|
||||||
|
readModule: Contract,
|
||||||
|
dummyImplementation: Contract
|
||||||
|
|
||||||
await greeter.deployed();
|
const proxyAdmin = '0x85B40eb65e49eB61De78a3a989752249f8837fc5'
|
||||||
|
|
||||||
console.log("Greeter deployed to:", greeter.address);
|
const UserModule = await ethers.getContractFactory(
|
||||||
|
"contracts/example/module1/main.sol:UserModule"
|
||||||
|
);
|
||||||
|
userModule = await UserModule.deploy();
|
||||||
|
await userModule.deployed();
|
||||||
|
console.log("User module deployed to: ", userModule.address);
|
||||||
|
|
||||||
|
const ReadModule = await ethers.getContractFactory(
|
||||||
|
"contracts/example/module2/main.sol:ReadModule"
|
||||||
|
);
|
||||||
|
readModule = await ReadModule.deploy();
|
||||||
|
await readModule.deployed();
|
||||||
|
console.log("Read module deployed to: ", readModule.address);
|
||||||
|
|
||||||
|
const DummyImplementation = await ethers.getContractFactory(
|
||||||
|
"contracts/example/dummyImplementation.sol:DummyImplementation"
|
||||||
|
);
|
||||||
|
dummyImplementation = await DummyImplementation.deploy();
|
||||||
|
await dummyImplementation.deployed();
|
||||||
|
console.log(
|
||||||
|
"Dummy Implementation deployed to: ",
|
||||||
|
dummyImplementation.address
|
||||||
|
);
|
||||||
|
|
||||||
|
const Proxy = await ethers.getContractFactory(
|
||||||
|
"contracts/example/proxy.sol:Example"
|
||||||
|
);
|
||||||
|
proxy = await Proxy.deploy(proxyAdmin, dummyImplementation.address);
|
||||||
|
await proxy.deployed();
|
||||||
|
console.log("Proxy deployed to: ", proxy.address);
|
||||||
|
|
||||||
|
let tx = await proxy.addImplementation(userModule.address, UserModuleSigs);
|
||||||
|
await tx.wait();
|
||||||
|
console.log("User Module implementation enabled!");
|
||||||
|
|
||||||
|
tx = await proxy.addImplementation(readModule.address, ReadModuleSigs);
|
||||||
|
await tx.wait();
|
||||||
|
console.log("Read Module implementation enabled!");
|
||||||
|
|
||||||
|
try {
|
||||||
|
await hre.run("verify:verify", {
|
||||||
|
address: userModule.address,
|
||||||
|
constructorArguments: [],
|
||||||
|
contract: "contracts/example/module1/main.sol:UserModule",
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
console.log("Failed to verify User Module");
|
||||||
|
console.log(error);
|
||||||
|
console.log();
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
await hre.run("verify:verify", {
|
||||||
|
address: readModule.address,
|
||||||
|
constructorArguments: [],
|
||||||
|
contract: "contracts/example/module2/main.sol:ReadModule",
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
console.log("Failed to verify Read Module");
|
||||||
|
console.log(error);
|
||||||
|
console.log();
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
await hre.run("verify:verify", {
|
||||||
|
address: dummyImplementation.address,
|
||||||
|
constructorArguments: [],
|
||||||
|
contract:
|
||||||
|
"contracts/example/dummyImplementation.sol:DummyImplementation",
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
console.log("Failed to verify Dummy Implementation");
|
||||||
|
console.log(error);
|
||||||
|
console.log();
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
await hre.run("verify:verify", {
|
||||||
|
address: proxy.address,
|
||||||
|
constructorArguments: [proxyAdmin, dummyImplementation.address],
|
||||||
|
contract: "contracts/example/proxy.sol:Example",
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
console.log("Failed to verify Proxy");
|
||||||
|
console.log(error);
|
||||||
|
console.log();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// We recommend this pattern to be able to use async/await everywhere
|
// We recommend this pattern to be able to use async/await everywhere
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user