-
Notifications
You must be signed in to change notification settings - Fork 88
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1349 from thesandboxgame/feat/marketplace-land-in…
…tegration-tests test: basic marketplace land integration test
- Loading branch information
Showing
10 changed files
with
361 additions
and
10 deletions.
There are no files selected for viewing
30 changes: 30 additions & 0 deletions
30
packages/deploy/deploy/000_core/001_deploy_polygon_land.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
import {DeployFunction} from 'hardhat-deploy/types'; | ||
import {HardhatRuntimeEnvironment} from 'hardhat/types'; | ||
|
||
const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { | ||
const {deployments, getNamedAccounts} = hre; | ||
const {deploy} = deployments; | ||
|
||
const {deployer, upgradeAdmin} = await getNamedAccounts(); | ||
|
||
const TRUSTED_FORWARDER_V2 = await deployments.get('TRUSTED_FORWARDER_V2'); | ||
|
||
await deploy('PolygonLand', { | ||
from: deployer, | ||
contract: | ||
'@sandbox-smart-contracts/core/src/solc_0.8/polygon/child/land/PolygonLandV2.sol:PolygonLandV2', | ||
proxy: { | ||
owner: upgradeAdmin, | ||
proxyContract: 'OpenZeppelinTransparentProxy', | ||
execute: { | ||
methodName: 'initialize', | ||
args: [TRUSTED_FORWARDER_V2.address], | ||
}, | ||
upgradeIndex: 0, | ||
}, | ||
log: true, | ||
}); | ||
}; | ||
export default func; | ||
func.tags = ['PolygonLand', 'PolygonLand_deploy', 'L2']; | ||
func.dependencies = ['TRUSTED_FORWARDER_V2']; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
import {DeployFunction} from 'hardhat-deploy/types'; | ||
import {HardhatRuntimeEnvironment} from 'hardhat/types'; | ||
|
||
export const royaltyAmount = 500; | ||
|
||
const func: DeployFunction = async function ( | ||
hre: HardhatRuntimeEnvironment | ||
): Promise<void> { | ||
const {deployments, getNamedAccounts} = hre; | ||
const {execute, read, catchUnknownSigner} = deployments; | ||
|
||
const {sandAdmin} = await getNamedAccounts(); | ||
const currentAdmin = await read('PolygonLand', {}, 'getAdmin'); | ||
if (currentAdmin !== sandAdmin) { | ||
await catchUnknownSigner( | ||
execute( | ||
'PolygonLand', | ||
{from: currentAdmin, log: true}, | ||
'changeAdmin', | ||
sandAdmin | ||
) | ||
); | ||
} | ||
}; | ||
|
||
export default func; | ||
func.tags = ['PolygonLand', 'PolygonLand_setup', 'L2']; | ||
func.dependencies = ['PolygonLand_deploy']; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
131 changes: 131 additions & 0 deletions
131
packages/deploy/integration_test/marketplaceLand/exchange.test.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,131 @@ | ||
import {getContract, withSnapshot} from '../../utils/testUtils'; | ||
import {expect} from 'chai'; | ||
import {ethers} from 'hardhat'; | ||
import {BigNumber} from 'ethers'; | ||
import {AssetERC20, AssetERC721, OrderDefault, signOrder} from './orders'; | ||
|
||
const setupTest = withSnapshot( | ||
['Exchange', 'PolygonSand', 'PolygonLand'], | ||
async (hre) => { | ||
const {sandAdmin} = await hre.getNamedAccounts(); | ||
const [user1, user2, minter] = await hre.getUnnamedAccounts(); | ||
|
||
const sandContract = await getContract(hre, 'PolygonSand'); | ||
|
||
const sandAdminSigner = await ethers.getSigner(sandAdmin); | ||
const landContract = await getContract(hre, 'PolygonLand', sandAdminSigner); | ||
await landContract.setMinter(minter, true); | ||
const landContractAsMinter = await landContract.connect( | ||
await ethers.getSigner(minter) | ||
); | ||
|
||
const childChainManager = await getContract( | ||
hre, | ||
'CHILD_CHAIN_MANAGER', | ||
sandAdminSigner | ||
); | ||
await childChainManager.setPolygonAsset(landContract.address); | ||
|
||
const exchangeAsUser2 = await getContract( | ||
hre, | ||
'Exchange', | ||
await ethers.getSigner(user2) | ||
); | ||
const orderValidatorAsAdmin = await getContract( | ||
hre, | ||
'OrderValidator', | ||
await ethers.getSigner(sandAdmin) | ||
); | ||
const TSB_ROLE = await orderValidatorAsAdmin.TSB_ROLE(); | ||
// enable land in whitelist | ||
await orderValidatorAsAdmin.grantRole( | ||
TSB_ROLE, | ||
landContractAsMinter.address | ||
); | ||
return { | ||
landContract, | ||
landContractAsMinter, | ||
sandContract, | ||
exchangeAsUser2, | ||
orderValidatorAsAdmin, | ||
sandAdmin, | ||
user1, | ||
user2, | ||
minter, | ||
mintSand: async (user: string, amount: BigNumber) => | ||
childChainManager.callSandDeposit( | ||
sandContract.address, | ||
user, | ||
ethers.utils.defaultAbiCoder.encode(['uint256'], [amount]) | ||
), | ||
}; | ||
} | ||
); | ||
|
||
describe('Marketplace Land <-> Sand exchange', function () { | ||
it('simple exchange', async function () { | ||
const { | ||
sandContract, | ||
landContractAsMinter, | ||
exchangeAsUser2, | ||
orderValidatorAsAdmin, | ||
user1, | ||
user2, | ||
mintSand, | ||
} = await setupTest(); | ||
const oneEth = ethers.utils.parseEther('1'); | ||
const landTokenId = 0; | ||
const size = 1; | ||
await landContractAsMinter.mintQuad(user1, size, 0, 0, '0x'); | ||
expect(await landContractAsMinter.balanceOf(user1)).to.be.equal( | ||
size * size | ||
); | ||
|
||
await mintSand(user2, oneEth); | ||
expect(await sandContract.balanceOf(user2)).to.be.equal(oneEth); | ||
|
||
await sandContract | ||
.connect(await ethers.getSigner(user2)) | ||
.approve(exchangeAsUser2.address, oneEth); | ||
await landContractAsMinter | ||
.connect(await ethers.getSigner(user1)) | ||
.approve(exchangeAsUser2.address, landTokenId); | ||
|
||
const makerAsset = await AssetERC721(landContractAsMinter, landTokenId); | ||
const takerAsset = await AssetERC20(sandContract, oneEth); | ||
const orderLeft = OrderDefault( | ||
user1, | ||
makerAsset, | ||
ethers.constants.AddressZero, | ||
takerAsset, | ||
1, | ||
0, | ||
0 | ||
); | ||
const orderRight = await OrderDefault( | ||
user2, | ||
takerAsset, | ||
ethers.constants.AddressZero, | ||
makerAsset, | ||
1, | ||
0, | ||
0 | ||
); | ||
const makerSig = await signOrder(orderLeft, user1, orderValidatorAsAdmin); | ||
const takerSig = await signOrder(orderRight, user2, orderValidatorAsAdmin); | ||
const tx = await exchangeAsUser2.matchOrders([ | ||
{ | ||
orderLeft, | ||
signatureLeft: makerSig, | ||
orderRight, | ||
signatureRight: takerSig, | ||
}, | ||
]); | ||
const receipt = await tx.wait(); | ||
console.log(receipt.gasUsed.toString()); | ||
expect(await landContractAsMinter.balanceOf(user2)).to.be.equal( | ||
size * size | ||
); | ||
expect(await sandContract.balanceOf(user1)).to.be.equal(oneEth); | ||
}); | ||
}); |
159 changes: 159 additions & 0 deletions
159
packages/deploy/integration_test/marketplaceLand/orders.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,159 @@ | ||
import {ethers} from 'hardhat'; | ||
import {BigNumber, BigNumberish, Contract} from 'ethers'; | ||
|
||
export const ASSET_TYPE_TYPEHASH = ethers.utils.keccak256( | ||
ethers.utils.toUtf8Bytes('AssetType(uint256 assetClass,bytes data)') | ||
); | ||
|
||
export function hashAssetType(a: AssetType) { | ||
if (a.assetClass === AssetClassType.INVALID_ASSET_CLASS) { | ||
throw new Error('Invalid assetClass' + a.assetClass); | ||
} | ||
return ethers.utils.keccak256( | ||
ethers.utils.defaultAbiCoder.encode( | ||
['bytes32', 'uint256', 'bytes32'], | ||
[ASSET_TYPE_TYPEHASH, a.assetClass, ethers.utils.keccak256(a.data)] | ||
) | ||
); | ||
} | ||
|
||
export function hashKey(order: Order): string { | ||
const encoded = ethers.utils.defaultAbiCoder.encode( | ||
['address', 'bytes32', 'bytes32', 'uint256'], | ||
[ | ||
order.maker, | ||
hashAssetType(order.makeAsset.assetType), | ||
hashAssetType(order.takeAsset.assetType), | ||
order.salt, | ||
] | ||
); | ||
return ethers.utils.keccak256(encoded); | ||
} | ||
|
||
export async function signOrder( | ||
order: Order, | ||
account: string, | ||
verifyingContract: Contract | ||
) { | ||
const network = await verifyingContract.provider.getNetwork(); | ||
return await ethers.provider.send('eth_signTypedData_v4', [ | ||
account, | ||
{ | ||
types: { | ||
EIP712Domain: [ | ||
{ | ||
name: 'name', | ||
type: 'string', | ||
}, | ||
{ | ||
name: 'version', | ||
type: 'string', | ||
}, | ||
{ | ||
name: 'chainId', | ||
type: 'uint256', | ||
}, | ||
{ | ||
name: 'verifyingContract', | ||
type: 'address', | ||
}, | ||
], | ||
AssetType: [ | ||
{name: 'assetClass', type: 'uint256'}, | ||
{name: 'data', type: 'bytes'}, | ||
], | ||
Asset: [ | ||
{name: 'assetType', type: 'AssetType'}, | ||
{name: 'value', type: 'uint256'}, | ||
], | ||
Order: [ | ||
{name: 'maker', type: 'address'}, | ||
{name: 'makeAsset', type: 'Asset'}, | ||
{name: 'taker', type: 'address'}, | ||
{name: 'takeAsset', type: 'Asset'}, | ||
{name: 'salt', type: 'uint256'}, | ||
{name: 'start', type: 'uint256'}, | ||
{name: 'end', type: 'uint256'}, | ||
], | ||
}, | ||
primaryType: 'Order', | ||
domain: { | ||
name: 'The Sandbox Marketplace', | ||
version: '1.0.0', | ||
chainId: network.chainId, | ||
verifyingContract: verifyingContract.address, | ||
}, | ||
message: order, | ||
}, | ||
]); | ||
} | ||
|
||
export type Order = { | ||
maker: string; | ||
makeAsset: Asset; | ||
taker: string; | ||
takeAsset: Asset; | ||
salt: string; | ||
start: string; | ||
end: string; | ||
}; | ||
|
||
export const OrderDefault = ( | ||
maker: string, | ||
makeAsset: Asset, | ||
taker: string, | ||
takeAsset: Asset, | ||
salt: BigNumberish, | ||
start: BigNumberish, | ||
end: BigNumberish | ||
): Order => ({ | ||
maker: maker, | ||
makeAsset, | ||
taker: taker, | ||
takeAsset, | ||
salt: BigNumber.from(salt).toString(), | ||
start: BigNumber.from(start).toString(), | ||
end: BigNumber.from(end).toString(), | ||
}); | ||
|
||
export enum AssetClassType { | ||
INVALID_ASSET_CLASS = '0x0', | ||
ERC20_ASSET_CLASS = '0x1', | ||
ERC721_ASSET_CLASS = '0x2', | ||
ERC1155_ASSET_CLASS = '0x3', | ||
} | ||
|
||
export type AssetType = { | ||
assetClass: AssetClassType; | ||
data: string; | ||
}; | ||
export type Asset = { | ||
assetType: AssetType; | ||
value: string; | ||
}; | ||
export const AssetERC20 = async ( | ||
tokenContract: Contract, | ||
value: BigNumberish | ||
): Promise<Asset> => ({ | ||
assetType: { | ||
assetClass: AssetClassType.ERC20_ASSET_CLASS, | ||
data: ethers.utils.defaultAbiCoder.encode( | ||
['address'], | ||
[tokenContract.address] | ||
), | ||
}, | ||
value: BigNumber.from(value).toString(), | ||
}); | ||
export const AssetERC721 = async ( | ||
tokenContract: Contract, | ||
tokenId: BigNumberish | ||
): Promise<Asset> => ({ | ||
assetType: { | ||
assetClass: AssetClassType.ERC721_ASSET_CLASS, | ||
data: ethers.utils.defaultAbiCoder.encode( | ||
['address', 'uint256'], | ||
[tokenContract.address, BigNumber.from(tokenId)] | ||
), | ||
}, | ||
value: BigNumber.from(1).toString(), | ||
}); |
2 changes: 1 addition & 1 deletion
2
..._test/multiGiveaway/multiGiveaway.test.ts → ...deploy/runtime_test/multiGiveaway.test.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.