Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: deployment scripts #75

Merged
merged 1 commit into from
Jan 14, 2025
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
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;
Comment on lines +54 to +55
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Temporary ownership is dropped when the subscription is set


// 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;
Comment on lines -56 to -65
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Subscription is set separately as it needs to be tied to this contract address

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) {
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As far as the understanding goes, all the fees are already accounted for when the subscription is paid for and mech gets its cleared cut.

// 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
Loading