Skip to content

Commit

Permalink
chore: deployment scripts
Browse files Browse the repository at this point in the history
  • Loading branch information
kupermind committed Jan 10, 2025
1 parent be4385c commit 23d5590
Show file tree
Hide file tree
Showing 22 changed files with 363 additions and 134 deletions.
2 changes: 0 additions & 2 deletions contracts/BalanceTrackerBase.sol
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,6 @@ abstract contract BalanceTrackerBase {
revert ZeroValue();
}

// TODO Separate between total fee and marketplace fee when NVM solution is ready
// Calculate mech payment and marketplace fee
uint256 fee = _getFee();

Expand All @@ -151,7 +150,6 @@ abstract contract BalanceTrackerBase {
// Calculate mech payment
mechPayment = balance - marketplaceFee;

// TODO If fee is charged beforehand, this is irrelevant
// Check for zero value, although this must never happen
if (marketplaceFee == 0 || mechPayment == 0) {
revert ZeroValue();
Expand Down
74 changes: 59 additions & 15 deletions contracts/mechs/nevermined/BalanceTrackerNvmSubscription.sol
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,11 @@ interface IERC1155 {
function safeTransferFrom(address from, address to, uint256 id, uint256 amount, bytes calldata) external;
}

/// @dev Only `owner` has a privilege, but the `sender` was provided.
/// @param sender Sender address.
/// @param owner Required sender address as an owner.
error OwnerOnly(address sender, address owner);

/// @dev Value overflow.
/// @param provided Overflow value.
/// @param max Maximum possible value.
Expand All @@ -34,35 +39,29 @@ error Overflow(uint256 provided, uint256 max);
error NoDepositAllowed(uint256 amount);

contract BalanceTrackerNvmSubscription is BalanceTrackerBase {
event SubscriptionSet(address indexed token, uint256 indexed tokenId);
event WithdrawSubscription(address indexed account, address indexed token, uint256 indexed tokenId, uint256 amount);
event RequesterCreditsRedeemed(address indexed account, uint256 amount);

// TODO: setup, taken from subscription?
uint256 public constant NVM_FEE = 100;

// Subscription NFT
address public immutable subscriptionNFT;
address public subscriptionNFT;
// Subscription token Id
uint256 public immutable subscriptionTokenId;
uint256 public subscriptionTokenId;

// Temporary owner address
address public owner;

// TODO Do we manage subscription fee via buyBackBurner as well or in-place?
/// @dev BalanceTrackerSubscription constructor.
/// @param _mechMarketplace Mech marketplace address.
/// @param _buyBackBurner Buy back burner address.
/// @param _subscriptionNFT Subscription NFT address.
/// @param _subscriptionTokenId Subscription token Id.
constructor(address _mechMarketplace, address _buyBackBurner, address _subscriptionNFT, uint256 _subscriptionTokenId)
constructor(address _mechMarketplace, address _buyBackBurner)
BalanceTrackerBase(_mechMarketplace, _buyBackBurner)
{
if (_subscriptionNFT == address(0)) {
revert ZeroAddress();
}

if (_subscriptionTokenId == 0) {
revert ZeroValue();
}

subscriptionNFT = _subscriptionNFT;
subscriptionTokenId = _subscriptionTokenId;
owner = msg.sender;
}

/// @dev Adjusts initial requester balance accounting for max request delivery rate (credit).
Expand Down Expand Up @@ -130,6 +129,26 @@ contract BalanceTrackerNvmSubscription is BalanceTrackerBase {
return 0;
}

/// @dev Process mech payment.
/// @param mech Mech address.
/// @return mechPayment Mech payment.
function _processPayment(address mech) internal virtual override returns (uint256 mechPayment, uint256) {
// Get mech balance
mechPayment = mapMechBalances[mech];
// Check for zero value
if (mechPayment == 0) {
revert ZeroValue();
}

// Clear balances
mapMechBalances[mech] = 0;

// Process withdraw
_withdraw(mech, mechPayment);

return (mechPayment, 0);
}

/// @dev Withdraws funds.
/// @param account Account address.
/// @param amount Token amount.
Expand All @@ -140,6 +159,31 @@ contract BalanceTrackerNvmSubscription is BalanceTrackerBase {
emit WithdrawSubscription(msg.sender, subscriptionNFT, subscriptionTokenId, amount);
}

/// @dev Sets subscription.
/// @param _subscriptionNFT Subscription NFT address.
/// @param _subscriptionTokenId Subscription token Id.
function setSubscription(address _subscriptionNFT, uint256 _subscriptionTokenId) external {
// Check for ownership
if (msg.sender != owner) {
revert OwnerOnly(msg.sender, owner);
}

if (_subscriptionNFT == address(0)) {
revert ZeroAddress();
}

if (_subscriptionTokenId == 0) {
revert ZeroValue();
}

subscriptionNFT = _subscriptionNFT;
subscriptionTokenId = _subscriptionTokenId;

owner = address(0);

emit SubscriptionSet(_subscriptionNFT, _subscriptionTokenId);
}

/// @dev Redeem requester credits.
/// @param requester Requester address.
function redeemRequesterCredits(address requester) external {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ async function main() {
console.log("EOA is:", deployer);

// Transaction signing and execution
console.log("4. EOA to deploy Karma");
console.log("1. EOA to deploy Karma");
console.log("You are signing the following transaction: Karma.connect(EOA).deploy()");
const gasPrice = ethers.utils.parseUnits(gasPriceInGwei, "gwei");
const Karma = await ethers.getContractFactory("Karma");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ async function main() {
const proxyData = karma.interface.encodeFunctionData("initialize", []);

// Transaction signing and execution
console.log("5. EOA to deploy Karma Proxy");
console.log("2. EOA to deploy Karma Proxy");
console.log("You are signing the following transaction: KarmaProxy.connect(EOA).deploy()");
const gasPrice = ethers.utils.parseUnits(gasPriceInGwei, "gwei");
const KarmaProxy = await ethers.getContractFactory("KarmaProxy");
Expand All @@ -68,7 +68,7 @@ async function main() {
// Contract verification
if (parsedData.contractVerification) {
const execSync = require("child_process").execSync;
execSync("npx hardhat verify --constructor-args scripts/deployment/verify_05_karma_proxy.js --network " + providerName + " " + karmaProxy.address, { encoding: "utf-8" });
execSync("npx hardhat verify --constructor-args scripts/deployment/verify_02_karma_proxy.js --network " + providerName + " " + karmaProxy.address, { encoding: "utf-8" });
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,8 @@ async function main() {
const derivationPath = parsedData.derivationPath;
const providerName = parsedData.providerName;
const gasPriceInGwei = parsedData.gasPriceInGwei;
const stakingFactoryAddress = parsedData.stakingFactoryAddress;
const serviceRegistryAddress = parsedData.serviceRegistryAddress;
const karmaProxyAddress = parsedData.karmaProxyAddress;
const minResponseTimeout = parsedData.minResponseTimeout;
const maxResponseTimeout = parsedData.maxResponseTimeout;

let networkURL = parsedData.networkURL;
if (providerName === "polygon") {
Expand Down Expand Up @@ -45,15 +43,13 @@ async function main() {
console.log("EOA is:", deployer);

// Transaction signing and execution
console.log("6. EOA to deploy Mech Marketplace");
console.log("3. EOA to deploy Mech Marketplace");
console.log("You are signing the following transaction: MechMarketplace.connect(EOA).deploy()");
const gasPrice = ethers.utils.parseUnits(gasPriceInGwei, "gwei");
const MechMarketplace = await ethers.getContractFactory("MechMarketplace");
const mechMarketplace = await MechMarketplace.connect(EOA).deploy(stakingFactoryAddress, karmaProxyAddress,
minResponseTimeout, maxResponseTimeout, { gasPrice });
const mechMarketplace = await MechMarketplace.connect(EOA).deploy(serviceRegistryAddress, karmaProxyAddress, { gasPrice });
// In case when gas calculation is not working correctly on Arbitrum
//const gasLimit = 60000000;
//const mechMarketplace = await MechMarketplace.connect(EOA).deploy(stakingFactoryAddress, { gasLimit });
const result = await mechMarketplace.deployed();

// Transaction details
Expand All @@ -71,7 +67,7 @@ async function main() {
// Contract verification
if (parsedData.contractVerification) {
const execSync = require("child_process").execSync;
execSync("npx hardhat verify --constructor-args scripts/deployment/verify_06_mech_marketplace.js --network " + providerName + " " + mechMarketplace.address, { encoding: "utf-8" });
execSync("npx hardhat verify --constructor-args scripts/deployment/verify_03_mech_marketplace.js --network " + providerName + " " + mechMarketplace.address, { encoding: "utf-8" });
}
}

Expand Down
86 changes: 86 additions & 0 deletions scripts/deployment/deploy_04_mech_marketplace_proxy.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
/*global process*/

const { ethers } = require("hardhat");
const { LedgerSigner } = require("@anders-t/ethers-ledger");

async function main() {
const fs = require("fs");
const globalsFile = "globals.json";
const dataFromJSON = fs.readFileSync(globalsFile, "utf8");
let parsedData = JSON.parse(dataFromJSON);
const useLedger = parsedData.useLedger;
const derivationPath = parsedData.derivationPath;
const providerName = parsedData.providerName;
const gasPriceInGwei = parsedData.gasPriceInGwei;
const mechMarketplaceAddress = parsedData.mechMarketplaceAddress;
const fee = parsedData.fee;
const minResponseTimeout = parsedData.minResponseTimeout;
const maxResponseTimeout = parsedData.maxResponseTimeout;

let networkURL = parsedData.networkURL;
if (providerName === "polygon") {
if (!process.env.ALCHEMY_API_KEY_MATIC) {
console.log("set ALCHEMY_API_KEY_MATIC env variable");
}
networkURL += process.env.ALCHEMY_API_KEY_MATIC;
} else if (providerName === "polygonMumbai") {
if (!process.env.ALCHEMY_API_KEY_MUMBAI) {
console.log("set ALCHEMY_API_KEY_MUMBAI env variable");
return;
}
networkURL += process.env.ALCHEMY_API_KEY_MUMBAI;
}

const provider = new ethers.providers.JsonRpcProvider(networkURL);
const signers = await ethers.getSigners();

let EOA;
if (useLedger) {
EOA = new LedgerSigner(provider, derivationPath);
} else {
EOA = signers[0];
}
// EOA address
const deployer = await EOA.getAddress();
console.log("EOA is:", deployer);

// Assemble the mech marketplace proxy data
const mechMarketplace = await ethers.getContractAt("MechMarketplace", mechMarketplaceAddress);
const proxyPayload = mechMarketplace.interface.encodeFunctionData("initialize", [fee, minResponseTimeout, maxResponseTimeout]);

// Transaction signing and execution
console.log("4. EOA to deploy Mech Marketplace Proxy");
console.log("You are signing the following transaction: MechMarketplaceProxy.connect(EOA).deploy()");
const gasPrice = ethers.utils.parseUnits(gasPriceInGwei, "gwei");
const MechMarketplaceProxy = await ethers.getContractFactory("MechMarketplaceProxy");
const mechMarketplaceProxy = await MechMarketplaceProxy.connect(EOA).deploy(mechMarketplaceAddress, proxyPayload,
{ gasPrice });
// In case when gas calculation is not working correctly on Arbitrum
//const gasLimit = 60000000;
const result = await mechMarketplaceProxy.deployed();

// Transaction details
console.log("Contract deployment: MechMarketplaceProxy");
console.log("Contract address:", mechMarketplaceProxy.address);
console.log("Transaction:", result.deployTransaction.hash);

// Wait for half a minute for the transaction completion
await new Promise(r => setTimeout(r, 30000));

// Writing updated parameters back to the JSON file
parsedData.mechMarketplaceProxyAddress = mechMarketplaceProxy.address;
fs.writeFileSync(globalsFile, JSON.stringify(parsedData));

// Contract verification
if (parsedData.contractVerification) {
const execSync = require("child_process").execSync;
execSync("npx hardhat verify --constructor-args scripts/deployment/verify_04_mech_marketplace_proxy.js --network " + providerName + " " + mechMarketplaceProxy.address, { encoding: "utf-8" });
}
}

main()
.then(() => process.exit(0))
.catch((error) => {
console.error(error);
process.exit(1);
});
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,7 @@ async function main() {
const derivationPath = parsedData.derivationPath;
const providerName = parsedData.providerName;
const gasPriceInGwei = parsedData.gasPriceInGwei;
const agentRegistryName = parsedData.agentRegistryName;
const agentRegistrySymbol = parsedData.agentRegistrySymbol;
const baseURI = parsedData.baseURI;
const mechMarketplaceProxyAddress = parsedData.mechMarketplaceProxyAddress;

let networkURL = parsedData.networkURL;
if (providerName === "polygon") {
Expand Down Expand Up @@ -44,29 +42,31 @@ async function main() {
console.log("EOA is:", deployer);

// Transaction signing and execution
console.log("1. EOA to deploy AgentRegistry");
const AgentRegistry = await ethers.getContractFactory("AgentRegistry");
console.log("You are signing the following transaction: AgentRegistry.connect(EOA).deploy()");
console.log("5. EOA to deploy Mech Factory NVM Subscription");
console.log("You are signing the following transaction: MechFactoryNvmSubscription.connect(EOA).deploy()");
const gasPrice = ethers.utils.parseUnits(gasPriceInGwei, "gwei");
const agentRegistry = await AgentRegistry.connect(EOA).deploy(agentRegistryName, agentRegistrySymbol, baseURI, { gasPrice });
const result = await agentRegistry.deployed();
const MechFactoryNvmSubscription = await ethers.getContractFactory("MechFactoryNvmSubscription");
const mechFactoryNvmSubscription = await MechFactoryNvmSubscription.connect(EOA).deploy(mechMarketplaceProxyAddress, { gasPrice });
// In case when gas calculation is not working correctly on Arbitrum
//const gasLimit = 60000000;
const result = await mechFactoryNvmSubscription.deployed();

// Transaction details
console.log("Contract deployment: AgentRegistry");
console.log("Contract address:", agentRegistry.address);
console.log("Contract deployment: MechFactoryNvmSubscription");
console.log("Contract address:", mechFactoryNvmSubscription.address);
console.log("Transaction:", result.deployTransaction.hash);

// Wait for half a minute for the transaction completion
await new Promise(r => setTimeout(r, 30000));

// Writing updated parameters back to the JSON file
parsedData.agentRegistryAddress = agentRegistry.address;
parsedData.mechFactoryNvmSubscriptionAddress = mechFactoryNvmSubscription.address;
fs.writeFileSync(globalsFile, JSON.stringify(parsedData));

// Contract verification
if (parsedData.contractVerification) {
const execSync = require("child_process").execSync;
execSync("npx hardhat verify --constructor-args scripts/deployment/verify_01_agent_registry.js --network " + providerName + " " + agentRegistry.address, { encoding: "utf-8" });
execSync("npx hardhat verify --constructor-args scripts/deployment/verify_05_mech_factory_nvm_subscription.js --network " + providerName + " " + mechFactoryNvmSubscription.address, { encoding: "utf-8" });
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,7 @@ async function main() {
const derivationPath = parsedData.derivationPath;
const providerName = parsedData.providerName;
const gasPriceInGwei = parsedData.gasPriceInGwei;
const agentRegistryAddress = parsedData.agentRegistryAddress;
const agentType = parsedData.agentType;
const mechMarketplaceProxyAddress = parsedData.mechMarketplaceProxyAddress;

let networkURL = parsedData.networkURL;
if (providerName === "polygon") {
Expand Down Expand Up @@ -43,41 +42,33 @@ async function main() {
console.log("EOA is:", deployer);

// Transaction signing and execution
console.log("2. EOA to deploy AgentFactory pointed to AgentRegistry");
let AgentFactory;
if (agentType === "subscription") {
AgentFactory = await ethers.getContractFactory("AgentFactorySubscription");
} else {
AgentFactory = await ethers.getContractFactory("AgentFactory");
}
console.log("You are signing the following transaction: AgentFactory.connect(EOA).deploy()");
console.log("5. EOA to deploy Balance Tracker NVM Subscription");
console.log("You are signing the following transaction: BalanceTrackerNvmSubscription.connect(EOA).deploy()");
const gasPrice = ethers.utils.parseUnits(gasPriceInGwei, "gwei");
const agentFactory = await AgentFactory.connect(EOA).deploy(agentRegistryAddress, { gasPrice });
const BalanceTrackerNvmSubscription = await ethers.getContractFactory("BalanceTrackerNvmSubscription");
// TODO Decide on buyBackBurner, now just mechMarketplace address
const balanceTrackerNvmSubscription = await BalanceTrackerNvmSubscription.connect(EOA).deploy(mechMarketplaceProxyAddress,
mechMarketplaceProxyAddress, { gasPrice });
// In case when gas calculation is not working correctly on Arbitrum
//const gasLimit = 60000000;
//const agentFactory = await AgentFactory.connect(EOA).deploy(agentRegistryAddress, { gasLimit });
const result = await agentFactory.deployed();
const result = await balanceTrackerNvmSubscription.deployed();

// Transaction details
console.log("Contract deployment: AgentFactory");
console.log("Contract address:", agentFactory.address);
console.log("Contract deployment: BalanceTrackerNvmSubscription");
console.log("Contract address:", balanceTrackerNvmSubscription.address);
console.log("Transaction:", result.deployTransaction.hash);

// Wait for half a minute for the transaction completion
await new Promise(r => setTimeout(r, 30000));

// Writing updated parameters back to the JSON file
if (agentType === "subscription") {
parsedData.agentFactorySubscriptionAddress = agentFactory.address;
} else {
parsedData.agentFactoryAddress = agentFactory.address;
}
parsedData.balanceTrackerNvmSubscriptionAddress = balanceTrackerNvmSubscription.address;
fs.writeFileSync(globalsFile, JSON.stringify(parsedData));

// Contract verification
if (parsedData.contractVerification) {
const execSync = require("child_process").execSync;
execSync("npx hardhat verify --constructor-args scripts/deployment/verify_02_agent_factory.js --network " + providerName + " " + agentFactory.address, { encoding: "utf-8" });
execSync("npx hardhat verify --constructor-args scripts/deployment/verify_06_balance_tracker_nvm_subscription.js --network " + providerName + " " + balanceTrackerNvmSubscription.address, { encoding: "utf-8" });
}
}

Expand Down
Loading

0 comments on commit 23d5590

Please sign in to comment.