Skip to content

Commit

Permalink
Merge pull request #25 from bitmark-inc/fix-audit-issue
Browse files Browse the repository at this point in the history
Fix the audit report issue
  • Loading branch information
Jim Yeh authored Jul 17, 2023
2 parents 862e6c8 + 8ec094f commit e001fee
Show file tree
Hide file tree
Showing 2 changed files with 158 additions and 10 deletions.
29 changes: 20 additions & 9 deletions contracts/FeralfileArtworkV4.sol
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,12 @@ contract FeralfileExhibitionV4 is

// initialize max supply map
for (uint256 i = 0; i < seriesIds_.length; i++) {
// Check duplicate with others
for (uint256 j = i + 1; j < seriesIds_.length; j++) {
if (seriesIds_[i] == seriesIds_[j]) {
revert("FeralfileExhibitionV4: duplicate seriesId");
}
}
require(
seriesMaxSupplies_[i] > 0,
"FeralfileExhibitionV4: zero max supply"
Expand Down Expand Up @@ -440,6 +446,11 @@ contract FeralfileExhibitionV4 is
) {
uint256 rev = (itemRevenue *
saleData_.revenueShares[i][j].bps) / 10000;
if (
saleData_.revenueShares[i][j].recipient == costReceiver
) {
continue;
}
distributedRevenue += rev;
payable(saleData_.revenueShares[i][j].recipient).transfer(
rev
Expand All @@ -450,10 +461,15 @@ contract FeralfileExhibitionV4 is
emit BuyArtwork(saleData_.destination, saleData_.tokenIds[i]);
}

// Transfer cost and remaining funds
uint256 cost = saleData_.price - distributedRevenue;
if (cost > 0) {
payable(costReceiver).transfer(cost);
require(
saleData_.price - saleData_.cost >= distributedRevenue,
"FeralfileExhibitionV4: total bps over 10,000"
);

// Transfer cost, platform revenue and remaining funds
uint256 leftOver = saleData_.price - distributedRevenue;
if (leftOver > 0) {
payable(costReceiver).transfer(leftOver);
}
}

Expand Down Expand Up @@ -596,11 +612,6 @@ contract FeralfileExhibitionV4 is
);
}

/// @notice withdraw all fund
function withdrawFunds() external onlyOwner {
payable(msg.sender).transfer(address(this).balance);
}

/// @notice Event emitted when new Artwork has been minted
event NewArtwork(
address indexed owner,
Expand Down
139 changes: 138 additions & 1 deletion test/feralfile_exhibition_v4.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ contract("FeralfileExhibitionV4_0", async (accounts) => {

// Deploy multiple contracts
this.contracts = [];
for (let i = 0; i < 7; i++) {
for (let i = 0; i < 8; i++) {
let contract = await FeralfileExhibitionV4.new(
"Feral File V4 Test",
"FFv4",
Expand Down Expand Up @@ -66,6 +66,32 @@ contract("FeralfileExhibitionV4_0", async (accounts) => {
assert.equal(seriesTotalSupply1, 0);
});

it("test duplicate series in constructor", async function () {
// Deploy contract with duplicate series defined
let seriesIds = [0, 1, 2, 3, 1];
let seriesMaxSupply = [1, 1, 100, 1000, 10000];
try {
await FeralfileExhibitionV4.new(
"Feral File V4 Test",
"FFv4",
true,
true,
this.signer,
this.vault.address,
COST_RECEIVER,
CONTRACT_URI,
seriesIds,
seriesMaxSupply
);
} catch (error) {
assert.ok(
error.message.includes(
"FeralfileExhibitionV4: duplicate seriesId"
)
);
}
})

it("test mint artwork", async function () {
const contract = this.contracts[0];

Expand Down Expand Up @@ -557,6 +583,117 @@ contract("FeralfileExhibitionV4_0", async (accounts) => {
}
});

it("test buy artworks failed with total bps over 10k", async function () {
let contract = this.contracts[7];

// Mint for buy by crypto
let owner = contract.address;
await contract.mintArtworks([
[this.seriesIds[3], 3000000, owner],
[this.seriesIds[3], 3000001, owner],
[this.seriesIds[4], 4000000, owner],
[this.seriesIds[4], 4000001, owner],
[this.seriesIds[4], 4000002, owner],
]);

// Generate signature
const expiryTime = (new Date().getTime() / 1000 + 300).toFixed(0);
const signParams = web3.eth.abi.encodeParameters(
[
"uint",
"address",
"tuple(uint256,uint256,uint256,address,uint256[],tuple(address,uint256)[][],bool)",
],
[
BigInt(await web3.eth.getChainId()).toString(),
contract.address,
[
BigInt(0.25 * 1e18).toString(),
BigInt(0.02 * 1e18).toString(),
expiryTime,
accounts[2],
[3000000, 3000001, 4000000, 4000001, 4000002],
[
[
[accounts[3], 8001],
[accounts[4], 2000],
],
[
[accounts[3], 8001],
[accounts[4], 2000],
],
[
[accounts[3], 9000],
[accounts[4], 2000],
],
[
[accounts[3], 9000],
[accounts[4], 2000],
],
[
[accounts[3], 8500],
[accounts[4], 2000],
],
],
false,
],
]
);
const hash = web3.utils.keccak256(signParams);
var sig = await web3.eth.sign(hash, this.signer);
sig = sig.substr(2);
const r = "0x" + sig.slice(0, 64);
const s = "0x" + sig.slice(64, 128);
const v = "0x" + sig.slice(128, 130);
// Generate signature

try {
await contract.startSale();
await contract.buyArtworks(
r,
s,
web3.utils.toDecimal(v) + 27, // magic 27
[
BigInt(0.25 * 1e18).toString(),
BigInt(0.02 * 1e18).toString(),
expiryTime,
accounts[2],
[3000000, 3000001, 4000000, 4000001, 4000002],
[
[
[accounts[3], 8001],
[accounts[4], 2000],
],
[
[accounts[3], 8001],
[accounts[4], 2000],
],
[
[accounts[3], 9000],
[accounts[4], 2000],
],
[
[accounts[3], 9000],
[accounts[4], 2000],
],
[
[accounts[3], 8500],
[accounts[4], 2000],
],
],
false,
],
{ from: accounts[5], value: 0.25 * 1e18 }
);
} catch (error) {
assert.ok(
error.message.includes(
"FeralfileExhibitionV4: total bps over 10,000"
)
);
}
});

it("test start/stop and burn, pause/resume sale", async function () {
const contract = this.contracts[4];

Expand Down

0 comments on commit e001fee

Please sign in to comment.