Skip to content

Commit

Permalink
Merge branch 'main' of github.com:killroy192/fortis-sdk into feat/fal…
Browse files Browse the repository at this point in the history
…lback-execution
  • Loading branch information
Tikhon committed Dec 3, 2023
2 parents c3f3a73 + 7c09b39 commit ddea8c8
Show file tree
Hide file tree
Showing 18 changed files with 250 additions and 157 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/quality-gate.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,5 +28,5 @@ jobs:
run: make lint
- name: Run unit tests
run: make test
- name: Run example deployment
run: make deploy-example
- name: Run demo deployment
run: make deploy-demo
6 changes: 3 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,10 @@ abi :; npx hardhat export-abi

network?=hardhat

deploy-example :; npx hardhat run --network $(network) scripts/deployment/example/$(network)
deploy-demo :; npx hardhat run --network $(network) scripts/deployment/example/$(network)

tes :; npx hardhat run --network $(network) scripts/e2e/example/trigger.js
auto-demo :; npx hardhat run --network $(network) scripts/e2e/example/$(script)

trade :; npx hardhat run --network arbitrum-goerli scripts/e2e/example/trade.js
trade-demo :; npx hardhat run --network $(network) scripts/e2e/example/trade.js

-include ${FCT_PLUGIN_PATH}/makefile-external
77 changes: 1 addition & 76 deletions deployment-lock.json

Large diffs are not rendered by default.

5 changes: 4 additions & 1 deletion scripts/common.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,12 @@ const fs = require("node:fs");
const path = require("node:path");
const hre = require("hardhat");

const loggedNetworks = ["arbitrum-sepolia", "arbitrum-goerli"];
const loggedNetworks = ["arbitrum-sepolia", "arbitrum-goerli", "localhost"];
const verifyNetwork = ["arbitrum-sepolia", "arbitrum-goerli"];
const filePath = path.resolve("deployment-lock.json");

const isLoggedNetwork = () => loggedNetworks.includes(hre.network.name);
const isVerifyNetwork = () => verifyNetwork.includes(hre.network.name);

const getDeploymentLockData = async () => {
const isExist = fs.existsSync(filePath);
Expand All @@ -25,6 +27,7 @@ const updateDeploymentLockData = (result) => {

module.exports = {
isLoggedNetwork,
isVerifyNetwork,
getDeploymentLockData,
updateDeploymentLockData,
}
19 changes: 19 additions & 0 deletions scripts/config.externals.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
module.exports = {
hardhat: {
verifier: ethers.ZeroAddress,
streamId: ethers.ZeroAddress,
datafeed: ethers.ZeroAddress,
},
"arbitrum-goerli": {
verifier: "0xcB1241Fdf26501fA7A2d47d841dcF72C3CAa9dCe",
streamId:
"0x00029584363bcf642315133c335b3646513c20f049602fc7d933be0d3f6360d3",
datafeed: "0xd30e2101a97dcbAeBCBC04F14C3f624E67A35165", // doesn't work
},
"arbitrum-sepolia": {
verifier: "0x2ff010DEbC1297f19579B4246cad07bd24F2488A",
streamId:
"0x00027bbaff688c906a3e20a34fe951715d1018d262a5b66e38eda027a674cd1b",
datafeed: "0xd30e2101a97dcbAeBCBC04F14C3f624E67A35165",
},
};
4 changes: 2 additions & 2 deletions scripts/deployment/deploy.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
const hre = require("hardhat");
const {
isLoggedNetwork,
isVerifyNetwork,
getDeploymentLockData,
updateDeploymentLockData,
} = require("../common");
Expand Down Expand Up @@ -69,7 +69,7 @@ const deployOnlyChanged =

console.log("Contract deployed, address:", contractAddress);

if (isLoggedNetwork()) {
if (isVerifyNetwork()) {
console.log("verify newly deployed contract...");

await hre.run("verify:verify", {
Expand Down
19 changes: 12 additions & 7 deletions scripts/deployment/example/arbitrum-goerli/config.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
const externals = require("../../../config.externals")["arbitrum-goerli"];

module.exports = [
{
contract: "RequestLib",
Expand All @@ -11,11 +13,11 @@ module.exports = [
// emitter
(deploymentLock) => deploymentLock.AutomationEmitter.addr,
// verifier
"0xcB1241Fdf26501fA7A2d47d841dcF72C3CAa9dCe",
externals.verifier,
// eth/usd data stream id
"0x00029584363bcf642315133c335b3646513c20f049602fc7d933be0d3f6360d3",
externals.streamId,
// eth/usd data feed
"0xd30e2101a97dcbAeBCBC04F14C3f624E67A35165",
externals.datafeed,
// timeout
5,
],
Expand All @@ -34,9 +36,12 @@ module.exports = [
},
{
contract: "SwapApp",
args: [
"0xab7664500b19a7a2362Ab26081e6DfB971B6F1B0",
(deploymentLock) => deploymentLock.FakedOracleProxy.addr
],
args: [(deploymentLock) => deploymentLock.FakedOracleProxy.addr],
},
{
contract: "FWETH",
},
{
contract: "FUSDC",
},
];
21 changes: 13 additions & 8 deletions scripts/deployment/example/arbitrum-sepolia/config.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
const externals = require("../../../config.externals")["arbitrum-sepolia"];

module.exports = [
{
contract: "RequestLib",
Expand All @@ -11,13 +13,13 @@ module.exports = [
// emitter
(deploymentLock) => deploymentLock.AutomationEmitter.addr,
// verifier
"0x2ff010DEbC1297f19579B4246cad07bd24F2488A",
externals.verifier,
// eth/usd data stream id
"0x00027bbaff688c906a3e20a34fe951715d1018d262a5b66e38eda027a674cd1b",
externals.streamId,
// eth/usd data feed
"0xd30e2101a97dcbAeBCBC04F14C3f624E67A35165",
externals.datafeed,
// timeout
5,
60,
],
deployerOptions: {
libs: {
Expand All @@ -34,9 +36,12 @@ module.exports = [
},
{
contract: "SwapApp",
args: [
"0xab7664500b19a7a2362Ab26081e6DfB971B6F1B0",
(deploymentLock) => deploymentLock.FakedOracleProxy.addr
],
args: [(deploymentLock) => deploymentLock.FakedOracleProxy.addr],
},
{
contract: "FWETH",
},
{
contract: "FUSDC",
},
];
19 changes: 12 additions & 7 deletions scripts/deployment/example/hardhat/config.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
const externals = require("../../../config.externals").hardhat;

module.exports = [
{
contract: "RequestLib",
Expand All @@ -11,11 +13,11 @@ module.exports = [
// emitter
(deploymentLock) => deploymentLock.AutomationEmitter.addr,
// verifier
"0x2ff010DEbC1297f19579B4246cad07bd24F2488A",
externals.verifier,
// eth/usd data stream id
"0x00027bbaff688c906a3e20a34fe951715d1018d262a5b66e38eda027a674cd1b",
externals.streamId,
// eth/usd data feed
"0xd30e2101a97dcbAeBCBC04F14C3f624E67A35165",
externals.datafeed,
// timeout
5,
],
Expand All @@ -34,9 +36,12 @@ module.exports = [
},
{
contract: "SwapApp",
args: [
"0xab7664500b19a7a2362Ab26081e6DfB971B6F1B0",
(deploymentLock) => deploymentLock.FakedOracleProxy.addr
],
args: [(deploymentLock) => deploymentLock.FakedOracleProxy.addr],
},
{
contract: "FWETH",
},
{
contract: "FUSDC",
},
];
11 changes: 11 additions & 0 deletions scripts/deployment/example/localhost/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
const deploy = require("../../deploy");
const upgrades = require("../upgrades");
const config = require("../hardhat/config");

async function main() {
const lock = await deploy(config);

return upgrades(lock, "0xb1d4538b4571d411f07960ef2838ce337fe1e80e");
}

main();
24 changes: 24 additions & 0 deletions scripts/e2e/example/fund.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
const { ethers } = require("hardhat");
const { getDeploymentLockData } = require("../../common");

/**
* Simple script to fund contract with custom usdc.
* Since usdc decimals is 6, ethers.parseEther("0.0001") will result to fund with 100k usdc
*/

async function main() {
const lock = (await getDeploymentLockData())[hre.network.name];

const usdc = await hre.ethers.getContractAt("FUSDC", lock.FUSDC.addr);

usdc.mint(lock.SwapApp.addr, ethers.parseEther("0.0001"));

console.log("Successfully fund swapApp with USDC");
}

// We recommend this pattern to be able to use async/await everywhere
// and properly handle errors.
main().catch((error) => {
console.error(error);
process.exitCode = 1;
});
86 changes: 63 additions & 23 deletions scripts/e2e/example/trade.js
Original file line number Diff line number Diff line change
@@ -1,40 +1,80 @@
const { ethers } = require("hardhat");
const { getDeploymentLockData } = require("../../common");

// arbitrum-goerli only
const coder = new ethers.AbiCoder();

/**
* Script to run simple trade on swap app via automation (data streams)
* also log states about execution from oracle side, aka is it possible to execute fallback
*/
async function main() {
console.log("prepare..");
const [signer] = await ethers.getSigners();
const lock = await getDeploymentLockData();
const signerAddr = await signer.getAddress();
const lock = (await getDeploymentLockData())[hre.network.name];

const consumer = await hre.ethers.getContractAt(
"SwapApp",
lock[hre.network.name].SwapApp.addr,
);
const consumer = await hre.ethers.getContractAt("SwapApp", lock.SwapApp.addr);

const wethAddress = "0xe39ab88f8a4777030a534146a9ca3b52bd5d43a3";
const usdc = "0x8fb1e3fc51f3b789ded7557e680551d93ea9d892";
const wethAddress = lock.FWETH.addr;
const usdcAddress = lock.FUSDC.addr;

const feedsId =
"0x00029584363bcf642315133c335b3646513c20f049602fc7d933be0d3f6360d3";
const weth = await ethers.getContractAt("FWETH", wethAddress);
console.log("done\n");

// Trade WETH <> USDC
const amountIn = ethers.parseEther("0.001");
console.log("get 0.001 weth for trading");
await weth.deposit({ value: amountIn });
console.log("done\n");
console.log("approve 0.001 weth for trade");
await weth.approve(lock.SwapApp.addr, amountIn);
console.log("done\n");
console.log("generate trade input");
const nonce = Math.ceil(Math.random() * 100);
const tradeArgs = {
recipient: signerAddr,
tokenIn: wethAddress,
tokenOut: usdcAddress,
amountIn: amountIn,
};
console.log("trade nonce", nonce);
console.log(
"tradeArgs",
JSON.stringify({
recipient: signerAddr,
tokenIn: wethAddress,
tokenOut: usdcAddress,
amountIn: "BigInt 0.001",
}),
);
console.log("done\n");
console.log("execute trade");
await consumer.trade(tradeArgs, nonce);
console.log("Successfully traded fWETH tokens for fUSDC");

// Trade WETH <> USDC
const weth = await ethers.getContractAt("IERC20", wethAddress);
console.log("run fallback check logic..");
const oracle = await hre.ethers.getContractAt(
"FakedOracleProxy",
lock.FakedOracleProxy.addr,
);

await weth.approve(await consumer.getAddress(), amountIn);
await consumer.trade(
{
recipient: await signer.getAddress(),
tokenIn: wethAddress,
tokenOut: usdc,
amountIn: amountIn,
feedId: feedsId
},
Math.ceil(Math.random() * 100),
const bytesCallbackArgs = coder.encode(
[
"tuple(address recipient, address tokenIn, address tokenOut, uint256 amountIn)",
],
[tradeArgs],
);

const result = await oracle.previewFallbackCall(
consumer,
bytesCallbackArgs,
nonce,
tradeArgs.recipient,
);
console.log("Successfully traded WETH tokens for USDC");

console.log("previewFallbackCall call result", result);

console.log("done\n");
}

// We recommend this pattern to be able to use async/await everywhere
Expand Down
3 changes: 3 additions & 0 deletions scripts/e2e/example/trigger.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
const hre = require("hardhat");
const { getDeploymentLockData } = require("../../common");

/**
* Simple scrip to trigger SimpleConsumer and verify that it works
*/
async function main() {
const lock = await getDeploymentLockData();

Expand Down
2 changes: 1 addition & 1 deletion src/Oracle.sol
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,7 @@ contract Oracle is IOracle, DataStreamConsumer, PriceFeedConsumer {
) = getRequestProps(callbackContract, callbackArgs, nonce, sender);

bool executable = reqStats.status ==
IRequestsManager.RequestStatus.Pending ||
IRequestsManager.RequestStatus.Pending &&
reqStats.blockNumber + requestTimeout > block.number;

return (id, executable);
Expand Down
3 changes: 3 additions & 0 deletions src/example/SimpleConsumer.sol
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ contract SimpleConsumer is IOracleConsumerContract {
uint256 amountIn;
}

event Price(int256 price);

error UnsuccesfullTrigger();

int256 public lastConsumedPrice;
Expand Down Expand Up @@ -68,6 +70,7 @@ contract SimpleConsumer is IOracleConsumerContract {
forwardData.forwardArguments,
(CustomRequestParams)
);
emit Price(forwardData.price);
return true;
}
}
Loading

0 comments on commit ddea8c8

Please sign in to comment.