Skip to content

Commit

Permalink
Merge pull request #1573 from thesandboxgame/fix/marketplace-bundle
Browse files Browse the repository at this point in the history
Fix MarketPlace contract and tests
  • Loading branch information
wojciech-turek authored Aug 16, 2024
2 parents 0082e5c + da3c326 commit 1443dc7
Show file tree
Hide file tree
Showing 28 changed files with 370 additions and 156 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) {
await deploy('RoyaltiesRegistry', {
from: deployer,
contract:
'@sandbox-smart-contracts/marketplace/contracts/RoyaltiesRegistry.sol:RoyaltiesRegistry',
'@sandbox-smart-contracts/marketplace@1.0.1/contracts/RoyaltiesRegistry.sol:RoyaltiesRegistry',
proxy: {
owner: upgradeAdmin,
proxyContract: 'OpenZeppelinTransparentProxy',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) {
await deploy('OrderValidator', {
from: deployer,
contract:
'@sandbox-smart-contracts/marketplace/contracts/OrderValidator.sol:OrderValidator',
'@sandbox-smart-contracts/marketplace@1.0.1/contracts/OrderValidator.sol:OrderValidator',
proxy: {
owner: upgradeAdmin,
proxyContract: 'OpenZeppelinTransparentProxy',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,12 @@ const func: DeployFunction = async function (
const TSB_ROLE = await read('OrderValidator', 'TSB_ROLE');
const PARTNER_ROLE = await read('OrderValidator', 'PARTNER_ROLE');

const SandContract = await deployments.get('PolygonSand');
let SandContract;
if (hre.network.name === 'polygon') {
SandContract = await deployments.get('PolygonSand');
} else {
SandContract = await deployments.get('Sand');
}
const AssetContract = await deployments.get('Asset');

const addressesToGrant = [];
Expand Down Expand Up @@ -110,5 +115,6 @@ func.tags = [
func.dependencies = [
'OrderValidator_deploy',
'PolygonSand_deploy',
'Sand_deploy',
'Asset_deploy',
];
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) {

await deploy('Exchange', {
from: deployer,
contract: `@sandbox-smart-contracts/marketplace/contracts/Exchange.sol:Exchange`,
contract: `@sandbox-smart-contracts/marketplace@1.0.1/contracts/Exchange.sol:Exchange`,
proxy: {
owner: upgradeAdmin,
proxyContract: 'OpenZeppelinTransparentProxy',
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import {DeployFunction} from 'hardhat-deploy/types';
import {HardhatRuntimeEnvironment} from 'hardhat/types';
import {DEPLOY_TAGS} from '../../hardhat.config';

const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) {
const {deployments, getNamedAccounts} = hre;
const {deploy, catchUnknownSigner} = deployments;
const {deployer, upgradeAdmin} = await getNamedAccounts();
await catchUnknownSigner(
deploy('RoyaltiesRegistry', {
from: deployer,
contract:
'@sandbox-smart-contracts/marketplace/contracts/RoyaltiesRegistry.sol:RoyaltiesRegistry',
proxy: {
owner: upgradeAdmin,
proxyContract: 'OpenZeppelinTransparentProxy',
upgradeIndex: 1,
},
log: true,
})
);
};

export default func;
func.tags = [
'RoyaltiesRegistry',
'RoyaltiesRegistry',
'RoyaltiesRegistryV2_deploy',
DEPLOY_TAGS.L1,
DEPLOY_TAGS.L1_PROD,
DEPLOY_TAGS.L1_TEST,
DEPLOY_TAGS.L2,
DEPLOY_TAGS.L2_PROD,
DEPLOY_TAGS.L2_TEST,
];
func.dependencies = ['RoyaltiesRegistry_deploy'];
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import {DeployFunction} from 'hardhat-deploy/types';
import {HardhatRuntimeEnvironment} from 'hardhat/types';
import {DEPLOY_TAGS} from '../../hardhat.config';

const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) {
const {deployments, getNamedAccounts} = hre;
const {deploy, catchUnknownSigner} = deployments;
const {deployer, upgradeAdmin} = await getNamedAccounts();
await catchUnknownSigner(
deploy('OrderValidator', {
from: deployer,
contract:
'@sandbox-smart-contracts/marketplace/contracts/OrderValidator.sol:OrderValidator',
proxy: {
owner: upgradeAdmin,
proxyContract: 'OpenZeppelinTransparentProxy',
upgradeIndex: 1,
},
log: true,
})
);
};

export default func;
func.tags = [
'OrderValidator',
'OrderValidator',
'OrderValidatorV2_deploy',
DEPLOY_TAGS.L1,
DEPLOY_TAGS.L1_PROD,
DEPLOY_TAGS.L1_TEST,
DEPLOY_TAGS.L2,
DEPLOY_TAGS.L2_PROD,
DEPLOY_TAGS.L2_TEST,
];
func.dependencies = ['OrderValidator_deploy'];
35 changes: 35 additions & 0 deletions packages/deploy/deploy/500_marketplace/507_upgrade_exchange.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import {DeployFunction} from 'hardhat-deploy/types';
import {HardhatRuntimeEnvironment} from 'hardhat/types';
import {DEPLOY_TAGS} from '../../hardhat.config';

const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) {
const {deployments, getNamedAccounts} = hre;
const {deploy, catchUnknownSigner} = deployments;
const {deployer, upgradeAdmin} = await getNamedAccounts();
await catchUnknownSigner(
deploy('Exchange', {
from: deployer,
contract: `@sandbox-smart-contracts/marketplace/contracts/Exchange.sol:Exchange`,
proxy: {
owner: upgradeAdmin,
proxyContract: 'OpenZeppelinTransparentProxy',
upgradeIndex: 1,
},
log: true,
})
);
};

export default func;
func.tags = [
'Exchange',
'Exchange',
'ExchangeV2_deploy',
DEPLOY_TAGS.L1,
DEPLOY_TAGS.L1_PROD,
DEPLOY_TAGS.L1_TEST,
DEPLOY_TAGS.L2,
DEPLOY_TAGS.L2_PROD,
DEPLOY_TAGS.L2_TEST,
];
func.dependencies = ['Exchange_deploy'];
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,16 @@ const func: DeployFunction = async function (

const ERC1776_OPERATOR_ROLE = await read('Exchange', 'ERC1776_OPERATOR_ROLE');
const EXCHANGE_ADMIN_ROLE = await read('Exchange', 'EXCHANGE_ADMIN_ROLE');
const sandContract = await deployments.get('PolygonSand');

let sandContract;
let landContract;
if (hre.network.name === 'polygon') {
sandContract = await deployments.get('PolygonSand');
landContract = await deployments.get('PolygonLand');
} else {
sandContract = await deployments.get('Sand');
landContract = await deployments.get('Land');
}

const hasERC1776OperatorRole = await read(
'Exchange',
Expand Down Expand Up @@ -48,6 +57,18 @@ const func: DeployFunction = async function (
)
);
}

const currentLand = await read('Exchange', 'landContract');
if (currentLand != landContract.address) {
await catchUnknownSigner(
execute(
'Exchange',
{from: sandAdmin, log: true},
'setLandContract',
landContract.address
)
);
}
};

export default func;
Expand All @@ -61,4 +82,13 @@ func.tags = [
DEPLOY_TAGS.L2_PROD,
DEPLOY_TAGS.L2_TEST,
];
func.dependencies = ['Exchange_deploy', 'PolygonSand_deploy'];
func.dependencies = [
'Exchange_deploy',
'Sand_deploy',
'Land_deploy',
'PolygonSand_deploy',
'PolygonLand_deploy',
'PolygonLandV2_deploy',
'LandV4_deploy',
'ExchangeV2_deploy',
];
7 changes: 7 additions & 0 deletions packages/deploy/hardhat.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,17 @@ const importedPackages = {
],
'@sandbox-smart-contracts/giveaway': 'contracts/SignedMultiGiveaway.sol',
'@sandbox-smart-contracts/faucets': 'contracts/FaucetsERC1155.sol',
'@sandbox-smart-contracts/[email protected]': [
'contracts/RoyaltiesRegistry.sol',
'contracts/OrderValidator.sol',
'contracts/Exchange.sol',
'contracts/TransferManager.sol',
],
'@sandbox-smart-contracts/marketplace': [
'contracts/RoyaltiesRegistry.sol',
'contracts/OrderValidator.sol',
'contracts/Exchange.sol',
'contracts/TransferManager.sol',
],
'@sandbox-smart-contracts/dependency-operator-filter': [
'contracts/OperatorFilterSubscription.sol',
Expand Down
3 changes: 2 additions & 1 deletion packages/deploy/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@
"@sandbox-smart-contracts/faucets": "0.0.1",
"@sandbox-smart-contracts/giveaway": "0.0.3",
"@sandbox-smart-contracts/land": "1.0.0-rc.1",
"@sandbox-smart-contracts/marketplace": "1.0.1",
"@sandbox-smart-contracts/marketplace": "1.0.2",
"@sandbox-smart-contracts/[email protected]": "npm:@sandbox-smart-contracts/[email protected]",
"@sandbox-smart-contracts/oft-sand": "0.0.1"
},
"files": [
Expand Down
4 changes: 0 additions & 4 deletions packages/land/contracts/interfaces/ILandToken.sol
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,4 @@ interface ILandToken is IQuad {
/// @param y y coordinate
/// @return does the LAND exist
function exists(uint256 size, uint256 x, uint256 y) external view returns (bool);

/// @notice total width of the map
/// @return width
function width() external pure returns (uint256);
}
5 changes: 3 additions & 2 deletions packages/marketplace/contracts/Exchange.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@

pragma solidity 0.8.23;

import {PausableUpgradeable} from "@openzeppelin/contracts-upgradeable/utils/PausableUpgradeable.sol";
import {PausableUpgradeable} from "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol";
import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
import {AccessControlEnumerableUpgradeable} from "@openzeppelin/contracts-upgradeable/access/extensions/AccessControlEnumerableUpgradeable.sol";
import {AccessControlEnumerableUpgradeable} from "@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol";
import {ContextUpgradeable} from "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol";
import {ERC2771HandlerUpgradeable} from "@sandbox-smart-contracts/dependency-metatx/contracts/ERC2771HandlerUpgradeable.sol";
import {IOrderValidator} from "./interfaces/IOrderValidator.sol";
Expand All @@ -14,6 +14,7 @@ import {ExchangeCore} from "./ExchangeCore.sol";

/// @author The Sandbox
/// @title Exchange contract with meta transactions
/// @custom:security-contact [email protected]
/// @notice Used to exchange assets, that is, tokens.
/// @dev Main functions are in ExchangeCore
/// @dev TransferManager is used to execute token transfers
Expand Down
5 changes: 4 additions & 1 deletion packages/marketplace/contracts/OrderValidator.sol
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import {LibAsset} from "./libraries/LibAsset.sol";
import {SignatureChecker} from "@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol";
import {EIP712Upgradeable, Initializable} from "@openzeppelin/contracts-upgradeable/utils/cryptography/EIP712Upgradeable.sol";
import {ERC165Upgradeable} from "@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol";
import {AccessControlEnumerableUpgradeable} from "@openzeppelin/contracts-upgradeable/access/extensions/AccessControlEnumerableUpgradeable.sol";
import {AccessControlEnumerableUpgradeable} from "@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol";
import {IOrderValidator} from "./interfaces/IOrderValidator.sol";
import {Whitelist} from "./Whitelist.sol";

Expand Down Expand Up @@ -64,6 +64,9 @@ contract OrderValidator is IOrderValidator, Initializable, EIP712Upgradeable, ER
require(order.maker.isValidSignatureNow(_hashTypedDataV4(hash), signature), "signature verification error");
}

/// @notice Check if the contract supports an interface
/// @param interfaceId The id of the interface
/// @return true if the interface is supported
function supportsInterface(
bytes4 interfaceId
)
Expand Down
5 changes: 4 additions & 1 deletion packages/marketplace/contracts/RoyaltiesRegistry.sol
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ contract RoyaltiesRegistry is OwnableUpgradeable, IRoyaltiesProvider, ERC165Upgr

/// @notice Royalties registry initializer
function initialize() external initializer {
__Ownable_init(_msgSender());
__Ownable_init();
}

/// @notice Assigns an external provider for a token's royalties and sets the royalty type as 'EXTERNAL_PROVIDER' (2).
Expand Down Expand Up @@ -158,6 +158,9 @@ contract RoyaltiesRegistry is OwnableUpgradeable, IRoyaltiesProvider, ERC165Upgr
return new Part[](0);
}

/// @notice Check if the contract supports an interface
/// @param interfaceId The id of the interface
/// @return true if the interface is supported
function supportsInterface(
bytes4 interfaceId
) public view virtual override(ERC165Upgradeable, IRoyaltiesProvider) returns (bool) {
Expand Down
23 changes: 18 additions & 5 deletions packages/marketplace/contracts/TransferManager.sol
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@ abstract contract TransferManager is Initializable, ITransferManager {
/// @notice cannot exceed 50% == 0.5 * BASE_POINTS == 5000
uint256 internal constant ROYALTY_SHARE_LIMIT = 5000;

/// @dev grid size of the land used to calculate ids
uint256 internal constant GRID_SIZE = 408;

/// @notice Fee applied to primary sales.
/// @return uint256 of primary sale fee in PROTOCOL_FEE_MULTIPLIER units
uint256 public protocolFeePrimary;
Expand Down Expand Up @@ -144,8 +147,10 @@ abstract contract TransferManager is Initializable, ITransferManager {
/// @notice Sets the LAND contract address.
/// @param newLandContractAddress Address of new LAND contract
function _setLandContract(ILandToken newLandContractAddress) internal {
// TODO: uncomment when ILandToken is supported by LandBase
// require(ERC165Checker.supportsInterface(address(newLandContractAddress, type(ILandToken).interfaceId), "invalid LAND address");
require(
ERC165Checker.supportsInterface(address(newLandContractAddress), type(ILandToken).interfaceId),
"Invalid LAND address"
);
landContract = newLandContractAddress;

emit LandContractSet(newLandContractAddress);
Expand Down Expand Up @@ -277,6 +282,13 @@ abstract contract TransferManager is Initializable, ITransferManager {
return remainder;
}

/// @notice Apply and transfer royalties based on the asset price and royalties information.
/// @param remainder How much of the amount left after previous transfers
/// @param paymentSide DealSide of the fee-side order
/// @param assetPrice The price of the asset for which royalties are being calculated.
/// @param royalties The array of royalty recipients and their respective basis points.
/// @param recipient The recipient who will receive the remainder after royalties are deducted.
/// @return How much left after paying royalties
function _applyRoyalties(
uint256 remainder,
DealSide memory paymentSide,
Expand Down Expand Up @@ -309,6 +321,7 @@ abstract contract TransferManager is Initializable, ITransferManager {
/// @notice Do a transfer based on a percentage (in basis points)
/// @param remainder How much of the amount left after previous transfers
/// @param paymentSide DealSide of the fee-side order
/// @param assetPrice The price of the asset for which royalties are being calculated.
/// @param to Account that will receive the asset
/// @param percentage Percentage to be transferred multiplied by the multiplier
/// @param multiplier Percentage is multiplied by this number to avoid rounding (2.5% == 0.025) * multiplier
Expand Down Expand Up @@ -441,7 +454,7 @@ abstract contract TransferManager is Initializable, ITransferManager {
IERC1155(token).safeTransferFrom(from, to, id, supply, "");
}

/// @notice Function deciding if the fees are applied or not, to be override
/// @notice Function deciding if the fees are applied or not, to be overridden
/// @param from Address to check
function _mustSkipFees(address from) internal virtual returns (bool);

Expand All @@ -454,11 +467,11 @@ abstract contract TransferManager is Initializable, ITransferManager {
/// @dev this method is gas optimized, must be called with verified x,y and size, after a call to _isValidQuad
function idInPath(uint256 i, uint256 size, uint256 x, uint256 y) internal view returns (uint256) {
unchecked {
return (x + (i % size)) + (y + (i / size)) * landContract.width();
return (x + (i % size)) + (y + (i / size)) * GRID_SIZE;
}
}

/// @notice Function deciding if the seller is a TSB seller, to be override
/// @notice Function deciding if the seller is a TSB seller, to be overridden
/// @param from Address to check
function _isTSBSeller(address from) internal virtual returns (bool);

Expand Down
3 changes: 2 additions & 1 deletion packages/marketplace/contracts/Whitelist.sol
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
// SPDX-License-Identifier: MIT

pragma solidity 0.8.23;

import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
import {AccessControlEnumerableUpgradeable} from "@openzeppelin/contracts-upgradeable/access/extensions/AccessControlEnumerableUpgradeable.sol";
import {AccessControlEnumerableUpgradeable} from "@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol";
import {IWhitelist} from "./interfaces/IWhitelist.sol";

/// @author The Sandbox
Expand Down
3 changes: 3 additions & 0 deletions packages/marketplace/contracts/interfaces/IOrderValidator.sol
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,8 @@ interface IOrderValidator {
/// @param sender Order sender
function validate(LibOrder.Order memory order, bytes memory signature, address sender) external view;

/// @notice Check if the contract supports an interface
/// @param interfaceId The id of the interface
/// @return true if the interface is supported
function supportsInterface(bytes4 interfaceId) external view returns (bool);
}
Loading

0 comments on commit 1443dc7

Please sign in to comment.