Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ jobs:
forge build --sizes
id: build

- name: Run Forge tests
run: |
forge test -vvv
id: test
# - name: Run Forge tests
# run: |
# forge test -vvv
# id: test
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ out/
# Docs
docs/

don-reports/

# Node modules
**/node_modules/
# Dotenv file
Expand Down
32 changes: 32 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,38 @@ simulate-don:
printf "%s\n" "Launching local don simulator..." && \
npx tsx ./don-simulator/src/localFunctionsTestnet.ts

setup-functions:
forge script script/FunctionsScript.s.sol:FunctionsScript --rpc-url http://localhost:8545 --private-key $(DEFAULT_ANVIL_KEY) --broadcast

# Interactions with the DON via the DataProvider contract
send-request:
forge script script/Interactions.s.sol:Interactions --sig "sendRequest()" --rpc-url http://localhost:8545 --private-key $(DEFAULT_ANVIL_KEY) --broadcast -vvvvv

get-last-response:
forge script script/Interactions.s.sol:Interactions --sig "getLastResponse()" --rpc-url http://localhost:8545 --private-key $(DEFAULT_ANVIL_KEY) --broadcast -vvvvv

get-last-error:
cast call $(CONTRACT_ADDRESS) "getLastError()" --rpc-url http://localhost:8545 --private-key $(DEFAULT_ANVIL_KEY)

get-last-request-id:
cast call $(CONTRACT_ADDRESS) "getLastRequestId()" --rpc-url http://localhost:8545 --private-key $(DEFAULT_ANVIL_KEY)

# Deploy the MADT and Vault contract
deploy-madt:
forge script script/DeployMADT.s.sol:DeployMADT --rpc-url http://localhost:8545 --private-key $(DEFAULT_ANVIL_KEY) --broadcast

deploy-vault:
forge script script/DeployVault.s.sol:DeployVault --rpc-url http://localhost:8545 --private-key $(DEFAULT_ANVIL_KEY) --broadcast -vvvvv

# Interactions with the Vault contract
# Deposit collateral
deposit-collateral:
forge script script/VaultInteractions.s.sol:VaultInteractions --sig "depositCollateral()" --rpc-url http://localhost:8545 --private-key $(DEFAULT_ANVIL_KEY) --broadcast -vvvvv

# Redeem collateral
redeem-collateral:
forge script script/VaultInteractions.s.sol:VaultInteractions --sig "redeemCollateral(uint256)" --rpc-url http://localhost:8545 --private-key $(DEFAULT_ANVIL_KEY) --broadcast -vvvvv

NETWORK_ARGS := --rpc-url http://localhost:8545 --private-key $(DEFAULT_ANVIL_KEY) --broadcast

ifeq ($(findstring --network sepolia,$(ARGS)),--network sepolia)
Expand Down
1 change: 1 addition & 0 deletions don-simulator/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@ export * from "./localFunctionsTestnet";
export * from "./types";
export * from "./buildRequestCBOR";
export * from "./simulationConfig";
export * from "./setSource";
16 changes: 13 additions & 3 deletions don-simulator/src/localFunctionsTestnet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,6 @@ export const startLocalFunctionsTestnet = async (
admin,
simulationConfigPath
);
console.log("✅ Request handled");
}
);

Expand Down Expand Up @@ -142,6 +141,8 @@ const handleOracleRequest = async (
.connect(admin)
.callReport(encodedReport, { gasLimit: callReportGasLimit });
await reportTx.wait(1);

console.log("✅ Request handled");
};

const simulateDONExecution = async (
Expand Down Expand Up @@ -451,9 +452,18 @@ export const deployFunctionsOracle = async (
console.log("Link token deployed at:", linkToken.address);
console.log("Don ID:", simulatedDonId);

fs.appendFileSync(
const envFile = fs.readFileSync(".env", "utf8");
const newEnv = envFile
.split("\n")
.filter((line) => !line.startsWith("MOCK_COORDINATOR_ADDRESS="))
.filter((line) => !line.startsWith("FUNCTIONS_ROUTER_ADDRESS="))
.filter((line) => !line.startsWith("LINK_TOKEN_ADDRESS="))
.filter((line) => !line.startsWith("DON_ID="))
.join("\n");
fs.writeFileSync(
".env",
`MOCK_COORDINATOR_ADDRESS=${mockCoordinator.address}\nFUNCTIONS_ROUTER_ADDRESS=${router.address}\nLINK_TOKEN_ADDRESS=${linkToken.address}\nDON_ID=${simulatedDonId}\n`
newEnv +
`\nMOCK_COORDINATOR_ADDRESS=${mockCoordinator.address}\nFUNCTIONS_ROUTER_ADDRESS=${router.address}\nLINK_TOKEN_ADDRESS=${linkToken.address}\nDON_ID=${simulatedDonId}\n`
);

return {
Expand Down
64 changes: 64 additions & 0 deletions don-simulator/src/setSource.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
#!/usr/bin/env node

import { ethers, providers } from "ethers";
import fs from "fs";
import path from "path";

async function main() {
const args = process.argv.slice(2);
if (args.length < 1) {
console.error("Usage: setSource <consumerAddress> [port]");
process.exit(1);
}

const consumerAddress = args[0];
const port = args[1] ? parseInt(args[1]) : 8545;

await setSource(consumerAddress, port);
}

async function setSource(consumerAddress: string, port: number = 8545) {
// Connect to local Anvil chain
const provider = new providers.JsonRpcProvider(`http://localhost:${port}`);

// Get the first signer account from Anvil
const signer = await provider.getSigner();

// ABI fragment for the function we need
const abi = [
{
inputs: [
{
internalType: "string",
name: "s_sourceCode",
type: "string",
},
],
name: "setSourceCode",
outputs: [],
stateMutability: "nonpayable",
type: "function",
},
];

// Create contract instance
const contract = new ethers.Contract(consumerAddress, abi, signer);

// Read the source code from file
const sourceCode = fs.readFileSync(path.join(__dirname, "./source/source.js")).toString();

// Set the source code
const tx = await contract.setSourceCode(sourceCode);
await tx.wait();

console.log("Source code set successfully");
}

if (require.main === module) {
main().catch((error) => {
console.error(error);
process.exit(1);
});
}

export { setSource };
2 changes: 2 additions & 0 deletions don-simulator/src/source/source.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
return Functions.encodeUint256(0.1 * 100);

2 changes: 2 additions & 0 deletions foundry.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ fs_permissions = [
{ access = "read", path = "lib/foundry-chainlink-toolkit/out" },
{ access = "read", path = "./broadcast" },
{ access = "read", path = "./reports" },
{ access = "read-write", path = "don-reports" },
{ access = "read-write", path = "don-simulator" },
]

src = "src"
Expand Down
13 changes: 13 additions & 0 deletions script/DeployMADT.s.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;

import {Script} from "forge-std/Script.sol";
import {MADT} from "../src/MADT.sol";

contract DeployMADT is Script {
function run() public {
vm.startBroadcast(vm.envUint("PRIVATE_KEY"));
new MADT();
vm.stopBroadcast();
}
}
28 changes: 28 additions & 0 deletions script/DeployVault.s.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;

import {Script, console} from "forge-std/Script.sol";
import {HelperConfig} from "./HelperConfig.s.sol";
import {IDataProvider} from "../src/interfaces/IDataProvider.sol";
import {FunctionsScript} from "./FunctionsScript.s.sol";
import {Vault} from "../src/Vault.sol";
import {MADT} from "../src/MADT.sol";
import {IERC20} from "openzeppelin-contracts/contracts/token/ERC20/IERC20.sol";
import {DevOpsTools} from "lib/foundry-devops/src/DevOpsTools.sol";

contract DeployVault is Script, HelperConfig {
IDataProvider public dataProvider;
address contractAddress = DevOpsTools.get_most_recent_deployment("DataProvider", block.chainid);
address MADTAddress = DevOpsTools.get_most_recent_deployment("MADT", block.chainid);

MADT public madt = MADT(MADTAddress);

function run() public {
vm.startBroadcast(vm.envUint("PRIVATE_KEY"));
dataProvider = IDataProvider(contractAddress);
IERC20 usdt = IERC20(getNetworkConfig().usdToken);
Vault vault = new Vault(dataProvider, madt, usdt);
// madt.setVault(address(vault));
vm.stopBroadcast();
}
}
43 changes: 17 additions & 26 deletions script/FunctionsScript.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ import {Script, console} from "forge-std/Script.sol";
import {HelperConfig} from "./HelperConfig.s.sol";
import {DataProvider} from "../src/DataProvider.sol";

import {IFunctionsSubscriptions} from "lib/foundry-chainlink-toolkit/src/interfaces/functions/IFunctionsSubscriptions.sol";
import {IFunctionsSubscriptions} from
"lib/foundry-chainlink-toolkit/src/interfaces/functions/IFunctionsSubscriptions.sol";
import {ILinkToken} from "src/interfaces/ILinkToken.sol";

/**
Expand All @@ -16,7 +17,6 @@ import {ILinkToken} from "src/interfaces/ILinkToken.sol";
* Deploy the allowlist with the functions coordinator address
* Update the allowlists and deploy a coordinator + set the don public keys.
*/

contract FunctionsScript is Script, HelperConfig {
uint256 public constant DEFAULT_SUB_TOPUP = 1000000000000000000;

Expand All @@ -27,43 +27,39 @@ contract FunctionsScript is Script, HelperConfig {
vm.startBroadcast(vm.envUint("PRIVATE_KEY"));
consumer = deployConsumer();
subscriptionId = createSubscription();
string memory jsonString = string(
abi.encodePacked(
'{"consumer":"', vm.toString(consumer), '","subscriptionId":', vm.toString(subscriptionId), "}"
)
);
vm.writeFile("don-reports/donDetails.json", jsonString);
console.log("Subscription ID: %s", subscriptionId);
console.log("Consumer: %s", consumer);

addConsumerToSubscription(subscriptionId, consumer);
fundSubscription(subscriptionId, DEFAULT_SUB_TOPUP);
vm.stopBroadcast();
}

function deployConsumer() public returns (address) {
DataProvider dataProvider = new DataProvider(
getNetworkConfig().router,
getNetworkConfig().donId
);
DataProvider dataProvider = new DataProvider(getNetworkConfig().router, getNetworkConfig().donId);
return address(dataProvider);
}

function createSubscription() public returns (uint64) {
IFunctionsSubscriptions functionsScript = IFunctionsSubscriptions(
getNetworkConfig().router
);
IFunctionsSubscriptions functionsScript = IFunctionsSubscriptions(getNetworkConfig().router);
subscriptionId = functionsScript.createSubscription();
return subscriptionId;
}
function addConsumerToSubscription(
uint64 subscriptionId,
address consumer
) public {
IFunctionsSubscriptions functionsScript = IFunctionsSubscriptions(
getNetworkConfig().router
);

function addConsumerToSubscription(uint64 subscriptionId, address consumer) public {
IFunctionsSubscriptions functionsScript = IFunctionsSubscriptions(getNetworkConfig().router);
functionsScript.addConsumer(subscriptionId, consumer);
}

function fundSubscription(uint64 subscriptionId, uint256 amount) public {
ILinkToken linkToken = ILinkToken(getNetworkConfig().linkToken);
linkToken.transferAndCall(
getNetworkConfig().router,
amount,
abi.encode(subscriptionId)
);
linkToken.transferAndCall(getNetworkConfig().router, amount, abi.encode(subscriptionId));
}

function getConsumer() public view returns (address) {
Expand All @@ -73,9 +69,4 @@ contract FunctionsScript is Script, HelperConfig {
function getSubscriptionId() public view returns (uint64) {
return subscriptionId;
}

function sendRequest() public {
DataProvider dataProvider = DataProvider(consumer);
dataProvider.sendRequest(subscriptionId);
}
}
19 changes: 6 additions & 13 deletions script/HelperConfig.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ pragma solidity ^0.8.24;
import {Script} from "forge-std/Script.sol";
import {console} from "forge-std/console.sol";

import {MockUSDT} from "../test/mocks/MockUSDT.sol";
import {MockUSDT} from "../src/MockUSDT.sol";

contract HelperConfig is Script {
// If we are on a local chain, we deploy the mock contract
Expand Down Expand Up @@ -32,11 +32,7 @@ contract HelperConfig is Script {
}
}

function getSepoliaEthConfig()
public
pure
returns (NetworkConfig memory sepoliaConfig)
{
function getSepoliaEthConfig() public pure returns (NetworkConfig memory sepoliaConfig) {
sepoliaConfig = NetworkConfig({
linkToken: 0x779877A7B0D9E8603169DdbD7836e478b4624789,
usdToken: 0x5f4eC3Df9cbd43714FE2740f5E3616155c5b8419,
Expand All @@ -49,11 +45,9 @@ contract HelperConfig is Script {
return sepoliaConfig;
}

function getAnvilEthConfig()
public
returns (NetworkConfig memory anvilConfig)
{
function getAnvilEthConfig() public returns (NetworkConfig memory anvilConfig) {
MockUSDT usdt = new MockUSDT();

anvilConfig = NetworkConfig({
linkToken: vm.envAddress("LINK_TOKEN_ADDRESS"),
usdToken: address(usdt),
Expand All @@ -67,12 +61,11 @@ contract HelperConfig is Script {
}

function getNetworkConfig() public view returns (NetworkConfig memory) {
console.log("Active network config:", activeNetworkConfig.usdToken);
return activeNetworkConfig;
}

function stringToBytes32(
string memory source
) public pure returns (bytes32 result) {
function stringToBytes32(string memory source) public pure returns (bytes32 result) {
bytes memory tempEmptyStringTest = bytes(source);
if (tempEmptyStringTest.length == 0) {
return 0x0;
Expand Down
Loading
Loading