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
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,6 @@
[submodule "lib/chainlink"]
path = lib/chainlink
url = https://github.com/smartcontractkit/chainlink
[submodule "lib/openzeppelin-foundry-upgrades"]
path = lib/openzeppelin-foundry-upgrades
url = https://github.com/OpenZeppelin/openzeppelin-foundry-upgrades
12 changes: 2 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,17 +81,9 @@ cast call <contract-address> "<function-signature>" --rpc-url $POLYGON_RPC_URL
```

## Contract Structure
- **VertixMarketplace.sol**: Core marketplace for minting, trading, borrowing, and staking NFTs.
- **Marketplace.sol**: Core marketplace for minting, trading, borrowing, and staking NFTs.

- **VertixEscrow.sol**: Manages secure escrow for manual asset transfers.

- **AssetVerifier.sol**: Handles asset authenticity verification.

#### Coming soon

> - **AssetRegistry.sol**: Tracks registered digital assets (NFTs, accounts, domains, apps).

> - **PaymentSplitter.sol**: Distributes fees and royalties to creators, platform, and other stakeholders.
- **Escrow.sol**: Manages secure escrow for manual asset transfers.


## Testing
Expand Down
1 change: 1 addition & 0 deletions lib/openzeppelin-foundry-upgrades
152 changes: 116 additions & 36 deletions script/DeployVertix.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -6,82 +6,162 @@ import {console} from "forge-std/console.sol";
import {HelperConfig} from "./HelperConfig.s.sol";
import {VertixNFT} from "../src/VertixNFT.sol";
import {VertixGovernance} from "../src/VertixGovernance.sol";
import {VertixEscrow} from "../src/VertixEscrow.sol";
import {VertixMarketplace} from "../src/VertixMarketplace.sol";
import {VertixEscrow} from "../src/VertixEscrow.sol"; // Using VertixEscrow as per your trace
import {MarketplaceStorage} from "../src/MarketplaceStorage.sol"; // Import MarketplaceStorage
import {MarketplaceCore} from "../src/MarketplaceCore.sol";
import {MarketplaceAuctions} from "../src/MarketplaceAuctions.sol";
import {MarketplaceFees} from "../src/MarketplaceFees.sol";
import {MarketplaceProxy} from "../src/MarketplaceProxy.sol";
import {ERC1967Proxy} from "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol";

contract DeployVertix is Script {
struct VertixAddresses {
address nft;
address governance;
address escrow;
address marketplace;
address marketplaceProxy;
address marketplaceCoreImpl; // Stores implementation address
address marketplaceAuctionsImpl; // Stores implementation address
address marketplaceFees;
address marketplaceStorage;
address verificationServer;
address feeRecipient;
}

function deployVertix() public returns (VertixAddresses memory) {
/// @notice Deploys all Vertix contracts and links them appropriately.
/// @param vertixAddresses A struct containing all deployed contract addresses.
/// @return vertixAddresses The populated struct with all deployed contract addresses.
function deployVertix() public returns (VertixAddresses memory vertixAddresses) {
HelperConfig helperConfig = new HelperConfig();
(address verificationServer, address feeRecipient, uint256 deployerKey) = helperConfig.activeNetworkConfig();

vm.startBroadcast(deployerKey);

// Deploy VertixNFT
address nft = deployProxy(
address(new VertixNFT()),
// Deploy MarketplaceStorage
address marketplaceStorage = address(new MarketplaceStorage(msg.sender)); // Pass deployer as initial owner
vertixAddresses.marketplaceStorage = marketplaceStorage;
console.log("MarketplaceStorage deployed at:", marketplaceStorage);

// Deploy VertixNFT (Implementation and Proxy)
address vertixNftImpl = address(new VertixNFT());
vertixAddresses.nft = deployProxy(
vertixNftImpl,
abi.encodeWithSelector(VertixNFT.initialize.selector, verificationServer),
"VertixNFT"
);

// Deploy VertixEscrow
address escrow = deployProxy(
address(new VertixEscrow()),
// Deploy Escrow (Implementation and Proxy)
address escrowImpl = address(new VertixEscrow());
vertixAddresses.escrow = deployProxy(
escrowImpl,
abi.encodeWithSelector(VertixEscrow.initialize.selector),
"VertixEscrow"
);

// Deploy VertixGovernance
address governance = deployProxy(
address(new VertixGovernance()),
// Deploy VertixGovernance (Implementation and Proxy)
// We temporarily pass address(0) for the marketplace and update it later.
address governanceImpl = address(new VertixGovernance());
vertixAddresses.governance = deployProxy(
governanceImpl,
abi.encodeWithSelector(
VertixGovernance.initialize.selector,
address(0), // Placeholder for marketplace (updated later)
escrow,
address(0),
vertixAddresses.escrow,
feeRecipient,
verificationServer
),
"VertixGovernance"
);

// Deploy VertixMarketplace
address marketplace = deployProxy(
address(new VertixMarketplace()),
abi.encodeWithSelector(
VertixMarketplace.initialize.selector, nft, governance, escrow
),
"VertixMarketplace"
// Deploy MarketplaceFees (Implementation)
// MarketplaceFees takes governance and escrow in its constructor (immutable).
// It's not proxied in this setup, as its logic is considered stable.
address marketplaceFeesImpl = address(new MarketplaceFees(vertixAddresses.governance, vertixAddresses.escrow));
vertixAddresses.marketplaceFees = marketplaceFeesImpl;
console.log("MarketplaceFees deployed at:", vertixAddresses.marketplaceFees);


// Deploy MarketplaceCore *Implementation*
// Its immutable dependencies (storage, fees, governance) are now known.
address marketplaceCoreImpl = address(
new MarketplaceCore(
vertixAddresses.marketplaceStorage,
vertixAddresses.marketplaceFees,
vertixAddresses.governance
)
);
vertixAddresses.marketplaceCoreImpl = marketplaceCoreImpl;
console.log("MarketplaceCore implementation deployed at:", marketplaceCoreImpl);

// Deploy MarketplaceAuctions *Implementation*
// Its immutable dependencies (storage, governance, escrow, fees) are now known.
address marketplaceAuctionsImpl = address(
new MarketplaceAuctions(
vertixAddresses.marketplaceStorage,
vertixAddresses.governance,
vertixAddresses.escrow,
vertixAddresses.marketplaceFees
)
);
vertixAddresses.marketplaceAuctionsImpl = marketplaceAuctionsImpl;
console.log("MarketplaceAuctions implementation deployed at:", marketplaceAuctionsImpl);

// Deploy the main MarketplaceProxy
// This proxy points to the *implementations* of Core and Auctions.
vertixAddresses.marketplaceProxy = address(new MarketplaceProxy(marketplaceCoreImpl, marketplaceAuctionsImpl));
console.log("Main MarketplaceProxy deployed at:", vertixAddresses.marketplaceProxy);

// Call `initialize` on MarketplaceCore *through the MarketplaceProxy*.
// Only initialize the primary contract (MarketplaceCore) via the proxy.
// This sets the `_initialized` flag in the proxy's storage.
MarketplaceCore(payable(vertixAddresses.marketplaceProxy)).initialize();
console.log("MarketplaceCore initialized via proxy.");

// Set essential contracts in MarketplaceStorage
// Authorize the deployed marketplace proxy and the core/auctions implementations if needed
// The `setContracts` in MarketplaceStorage needs to be called by its owner.
// In this script, `msg.sender` (the deployer) is the owner of MarketplaceStorage.
MarketplaceStorage(marketplaceStorage).setContracts(
vertixAddresses.nft, // VertixNFT proxy
vertixAddresses.governance, // VertixGovernance proxy
vertixAddresses.escrow // VertixEscrow proxy
);
console.log("MarketplaceStorage essential contracts set.");

// Authorize MarketplaceCore and MarketplaceAuctions implementations in MarketplaceStorage
// This allows them to call `onlyAuthorized` functions in storage.
MarketplaceStorage(marketplaceStorage).authorizeContract(vertixAddresses.marketplaceCoreImpl, true);
MarketplaceStorage(marketplaceStorage).authorizeContract(vertixAddresses.marketplaceAuctionsImpl, true);
console.log("MarketplaceCore and MarketplaceAuctions implementations authorized in Storage.");


// Update VertixGovernance with the main marketplace proxy address.
// This is done via the Governance proxy.
VertixGovernance(vertixAddresses.governance).setMarketplace(vertixAddresses.marketplaceProxy);
console.log("VertixGovernance marketplace set to:", vertixAddresses.marketplaceProxy);

// Update VertixGovernance with marketplace address
VertixGovernance(governance).setMarketplace(marketplace);
console.log("VertixGovernance marketplace set to:", marketplace);
// add VertixNFT contract as supported NFT contract
VertixGovernance(vertixAddresses.governance).addSupportedNFTContract(vertixAddresses.nft);

// Transfer VertixEscrow ownership to governance
VertixEscrow(escrow).transferOwnership(governance);
console.log("VertixEscrow ownership transferred to:", governance);
// Transfer Escrow ownership to governance.
// This is done via the Escrow proxy.
VertixEscrow(vertixAddresses.escrow).transferOwnership(vertixAddresses.governance);
console.log("Escrow ownership transferred to:", vertixAddresses.governance);

// Stop broadcasting transactions.
vm.stopBroadcast();

return VertixAddresses({
nft: nft,
governance: governance,
escrow: escrow,
marketplace: marketplace,
verificationServer: verificationServer,
feeRecipient: feeRecipient
});
// Return all deployed addresses.
vertixAddresses.verificationServer = verificationServer;
vertixAddresses.feeRecipient = feeRecipient;
return vertixAddresses;
}

/// @notice Helper function to deploy an ERC1967Proxy for an implementation contract.
/// @param impl The address of the implementation contract.
/// @param initData The encoded call to the `initialize` function (or constructor) of the implementation.
/// @param name A descriptive name for logging.
/// @return proxy The address of the deployed proxy.
function deployProxy(address impl, bytes memory initData, string memory name) internal returns (address proxy) {
console.log(string.concat(name, " implementation deployed at:"), impl);
proxy = address(new ERC1967Proxy(impl, initData));
Expand Down
Loading