marketplace: deploy vault and set it in the marketplace

This commit is contained in:
Mark Spanbroek 2025-02-24 17:11:00 +01:00
parent 341b303789
commit aee61bdb45
7 changed files with 55 additions and 28 deletions

View File

@ -3,6 +3,7 @@ pragma solidity ^0.8.28;
import "./TestToken.sol";
import "./Marketplace.sol";
import "./Vault.sol";
import "./TestVerifier.sol";
contract FuzzMarketplace is Marketplace {
@ -14,13 +15,10 @@ contract FuzzMarketplace is Marketplace {
SlotReservationsConfig(20),
60 * 60 * 24 * 30 // 30 days
),
new TestToken(),
new Vault(new TestToken()),
new TestVerifier()
)
// solhint-disable-next-line no-empty-blocks
{
}
{}
// Properties to be tested through fuzzing

View File

@ -5,6 +5,7 @@ import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import "@openzeppelin/contracts/utils/math/Math.sol";
import "@openzeppelin/contracts/utils/structs/EnumerableSet.sol";
import "./Vault.sol";
import "./Configuration.sol";
import "./Requests.sol";
import "./Proofs.sol";
@ -47,7 +48,7 @@ contract Marketplace is SlotReservations, Proofs, StateRetrieval, Endian {
using Requests for Request;
using AskHelpers for Ask;
IERC20 private immutable _token;
Vault private immutable _vault;
MarketplaceConfig private _config;
mapping(RequestId => Request) private _requests;
@ -99,10 +100,10 @@ contract Marketplace is SlotReservations, Proofs, StateRetrieval, Endian {
constructor(
MarketplaceConfig memory config,
IERC20 token_,
Vault vault_,
IGroth16Verifier verifier
) SlotReservations(config.reservations) Proofs(config.proofs, verifier) {
_token = token_;
_vault = vault_;
if (config.collateral.repairRewardPercentage > 100)
revert Marketplace_RepairRewardPercentageTooHigh();
@ -123,7 +124,11 @@ contract Marketplace is SlotReservations, Proofs, StateRetrieval, Endian {
}
function token() public view returns (IERC20) {
return _token;
return _vault.getToken();
}
function vault() public view returns (Vault) {
return _vault;
}
function currentCollateral(SlotId slotId) public view returns (uint256) {
@ -172,7 +177,7 @@ contract Marketplace is SlotReservations, Proofs, StateRetrieval, Endian {
uint256 amount = request.maxPrice();
_requestContexts[id].fundsToReturnToClient = amount;
_marketplaceTotals.received += amount;
_token.safeTransferFrom(msg.sender, address(this), amount);
token().safeTransferFrom(msg.sender, address(this), amount);
emit StorageRequested(id, request.ask, _requestContexts[id].expiresAt);
}
@ -232,7 +237,7 @@ contract Marketplace is SlotReservations, Proofs, StateRetrieval, Endian {
} else {
collateralAmount = collateralPerSlot;
}
_token.safeTransferFrom(msg.sender, address(this), collateralAmount);
token().safeTransferFrom(msg.sender, address(this), collateralAmount);
_marketplaceTotals.received += collateralAmount;
slot.currentCollateral = collateralPerSlot; // Even if he has collateral discounted, he is operating with full collateral
@ -358,7 +363,7 @@ contract Marketplace is SlotReservations, Proofs, StateRetrieval, Endian {
uint256 validatorRewardAmount = (slashedAmount *
_config.collateral.validatorRewardPercentage) / 100;
_marketplaceTotals.sent += validatorRewardAmount;
_token.safeTransfer(msg.sender, validatorRewardAmount);
token().safeTransfer(msg.sender, validatorRewardAmount);
slot.currentCollateral -= slashedAmount;
if (missingProofs(slotId) >= _config.collateral.maxNumberOfSlashes) {
@ -424,8 +429,8 @@ contract Marketplace is SlotReservations, Proofs, StateRetrieval, Endian {
uint256 collateralAmount = slot.currentCollateral;
_marketplaceTotals.sent += (payoutAmount + collateralAmount);
slot.state = SlotState.Paid;
_token.safeTransfer(rewardRecipient, payoutAmount);
_token.safeTransfer(collateralRecipient, collateralAmount);
token().safeTransfer(rewardRecipient, payoutAmount);
token().safeTransfer(collateralRecipient, collateralAmount);
}
/**
@ -454,8 +459,8 @@ contract Marketplace is SlotReservations, Proofs, StateRetrieval, Endian {
uint256 collateralAmount = slot.currentCollateral;
_marketplaceTotals.sent += (payoutAmount + collateralAmount);
slot.state = SlotState.Paid;
_token.safeTransfer(rewardRecipient, payoutAmount);
_token.safeTransfer(collateralRecipient, collateralAmount);
token().safeTransfer(rewardRecipient, payoutAmount);
token().safeTransfer(collateralRecipient, collateralAmount);
}
/**
@ -522,7 +527,7 @@ contract Marketplace is SlotReservations, Proofs, StateRetrieval, Endian {
uint256 amount = context.fundsToReturnToClient;
_marketplaceTotals.sent += amount;
_token.safeTransfer(withdrawRecipient, amount);
token().safeTransfer(withdrawRecipient, amount);
// We zero out the funds tracking in order to prevent double-spends
context.fundsToReturnToClient = 0;

View File

@ -7,10 +7,10 @@ import "./Marketplace.sol";
contract TestMarketplace is Marketplace {
constructor(
MarketplaceConfig memory config,
IERC20 token,
Vault vault,
IGroth16Verifier verifier
)
Marketplace(config, token, verifier) // solhint-disable-next-line no-empty-blocks
Marketplace(config, vault, verifier)
{}
function forciblyFreeSlot(SlotId slotId) public {

View File

@ -50,6 +50,10 @@ import "./vault/VaultBase.sol";
contract Vault is VaultBase, Pausable, Ownable {
constructor(IERC20 token) VaultBase(token) Ownable(msg.sender) {}
function getToken() public view returns (IERC20) {
return _token;
}
/// Creates an account id that encodes the address of the account holder, and
/// a discriminator. The discriminator can be used to create different
/// accounts within a fund that all belong to the same account holder.

View File

@ -9,12 +9,12 @@ async function mine256blocks({ network, ethers }) {
// deploys a marketplace with a real Groth16 verifier
async function deployMarketplace({ deployments, getNamedAccounts }) {
const token = await deployments.get("TestToken")
const vault = await deployments.get("Vault")
const verifier = await deployments.get("Groth16Verifier")
const zkeyHash = loadZkeyHash(network.name)
let configuration = loadConfiguration(network.name)
configuration.proofs.zkeyHash = zkeyHash
const args = [configuration, token.address, verifier.address]
const args = [configuration, vault.address, verifier.address]
const { deployer: from } = await getNamedAccounts()
const marketplace = await deployments.deploy("Marketplace", { args, from })
console.log("Deployed Marketplace with Groth16 Verifier at:")
@ -29,12 +29,12 @@ async function deployTestMarketplace({
getNamedAccounts,
}) {
if (network.tags.local) {
const token = await deployments.get("TestToken")
const vault = await deployments.get("Vault")
const verifier = await deployments.get("TestVerifier")
const zkeyHash = loadZkeyHash(network.name)
let configuration = loadConfiguration(network.name)
configuration.proofs.zkeyHash = zkeyHash
const args = [configuration, token.address, verifier.address]
const args = [configuration, vault.address, verifier.address]
const { deployer: from } = await getNamedAccounts()
const marketplace = await deployments.deploy("Marketplace", { args, from })
console.log("Deployed Marketplace with Test Verifier at:")
@ -50,4 +50,4 @@ module.exports = async (environment) => {
}
module.exports.tags = ["Marketplace"]
module.exports.dependencies = ["TestToken", "Verifier"]
module.exports.dependencies = ["Vault", "Verifier"]

13
deploy/vault.js Normal file
View File

@ -0,0 +1,13 @@
async function deployVault({ deployments, getNamedAccounts }) {
const token = await deployments.get("TestToken")
const args = [token.address]
const { deployer: from } = await getNamedAccounts()
await deployments.deploy("Vault", { args, from })
}
module.exports = async (environment) => {
await deployVault(environment)
}
module.exports.tags = ["Vault"]
module.exports.dependencies = ["TestToken"]

View File

@ -43,7 +43,7 @@ const { arrayify } = require("ethers/lib/utils")
const ACCOUNT_STARTING_BALANCE = 1_000_000_000_000_000
describe("Marketplace constructor", function () {
let Marketplace, token, verifier, config
let Marketplace, token, vault, verifier, config
beforeEach(async function () {
await snapshot()
@ -52,6 +52,9 @@ describe("Marketplace constructor", function () {
const TestToken = await ethers.getContractFactory("TestToken")
token = await TestToken.deploy()
const Vault = await ethers.getContractFactory("Vault")
vault = await Vault.deploy(token.address)
const TestVerifier = await ethers.getContractFactory("TestVerifier")
verifier = await TestVerifier.deploy()
@ -68,7 +71,7 @@ describe("Marketplace constructor", function () {
config.collateral[property] = 101
await expect(
Marketplace.deploy(config, token.address, verifier.address)
Marketplace.deploy(config, vault.address, verifier.address)
).to.be.revertedWith(expectedError)
})
}
@ -87,7 +90,7 @@ describe("Marketplace constructor", function () {
config.collateral.maxNumberOfSlashes = 101
await expect(
Marketplace.deploy(config, token.address, verifier.address)
Marketplace.deploy(config, vault.address, verifier.address)
).to.be.revertedWith("Marketplace_MaximumSlashingTooHigh")
})
})
@ -98,6 +101,7 @@ describe("Marketplace", function () {
let marketplace
let token
let vault
let verifier
let client,
clientWithdrawRecipient,
@ -143,13 +147,16 @@ describe("Marketplace", function () {
await token.mint(account.address, ACCOUNT_STARTING_BALANCE)
}
const Vault = await ethers.getContractFactory("Vault")
vault = await Vault.deploy(token.address)
const TestVerifier = await ethers.getContractFactory("TestVerifier")
verifier = await TestVerifier.deploy()
const Marketplace = await ethers.getContractFactory("TestMarketplace")
marketplace = await Marketplace.deploy(
config,
token.address,
vault.address,
verifier.address
)
patchOverloads(marketplace)