Skip to content

Commit

Permalink
Merge branch 'main' into verify-succesful-upgrade
Browse files Browse the repository at this point in the history
  • Loading branch information
zajck committed Nov 18, 2022
2 parents ceecbd2 + c518abf commit b98377d
Show file tree
Hide file tree
Showing 3 changed files with 74 additions and 7 deletions.
9 changes: 5 additions & 4 deletions contracts/protocol/bases/TwinBase.sol
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,10 @@ contract TwinBase is ProtocolBase, IBosonTwinEvents {
// Twin supply must exist and can't be zero
require(_twin.supplyAvailable > 0, INVALID_SUPPLY_AVAILABLE);

// Get the next twinId and increment the counter
uint256 twinId = protocolCounters().nextTwinId++;
_twin.id = twinId;

if (_twin.tokenType == TokenType.NonFungibleToken) {
// Check if the token supports IERC721 interface
require(contractSupportsInterface(_twin.tokenAddress, type(IERC721).interfaceId), INVALID_TOKEN_ADDRESS);
Expand Down Expand Up @@ -122,14 +126,11 @@ contract TwinBase is ProtocolBase, IBosonTwinEvents {
require(_twin.amount > 0 && _twin.amount <= _twin.supplyAvailable, INVALID_AMOUNT);
}

// Get the next twinId and increment the counter
uint256 twinId = protocolCounters().nextTwinId++;

// Get storage location for twin
(, Twin storage twin) = fetchTwin(twinId);

// Set twin props individually since memory structs can't be copied to storage
twin.id = _twin.id = twinId;
twin.id = twinId;
twin.sellerId = _twin.sellerId = sellerId;
twin.supplyAvailable = _twin.supplyAvailable;
twin.amount = _twin.amount;
Expand Down
70 changes: 68 additions & 2 deletions test/protocol/TwinHandlerTest.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
const hre = require("hardhat");
const ethers = hre.ethers;
const { expect, assert } = require("chai");

const Role = require("../../scripts/domain/Role");
const Twin = require("../../scripts/domain/Twin");
const Bundle = require("../../scripts/domain/Bundle");
Expand All @@ -13,10 +12,12 @@ const { deployProtocolDiamond } = require("../../scripts/util/deploy-protocol-di
const { deployProtocolHandlerFacets } = require("../../scripts/util/deploy-protocol-handler-facets.js");
const { deployProtocolConfigFacet } = require("../../scripts/util/deploy-protocol-config-facet.js");
const { deployProtocolClients } = require("../../scripts/util/deploy-protocol-clients");
const { getEvent } = require("../util/utils.js");
const { getEvent, getMappingStoragePosition, paddingType } = require("../util/utils.js");
const { deployMockTokens } = require("../../scripts/util/deploy-mock-tokens");
const { mockOffer, mockSeller, mockTwin, mockAuthToken, mockVoucherInitValues, accountId } = require("../util/mock");
const { oneWeek, oneMonth, maxPriorityFeePerGas } = require("../util/constants");
const { keccak256 } = ethers.utils;
const { getStorageAt } = require("@nomicfoundation/hardhat-network-helpers");

/**
* Test the Boson Twin Handler interface
Expand Down Expand Up @@ -381,6 +382,71 @@ describe("IBosonTwinHandler", function () {
await expect(twinHandler.connect(operator).createTwin(twin2)).not.to.be.reverted;
});

it("Should ignore twin id set by seller and use nextAccountId on twins entity", async function () {
twin.id = "666";
twin.tokenAddress = bosonToken.address;

// Approve twinHandler contract to transfer seller's tokens
await bosonToken.connect(operator).approve(twinHandler.address, 1);

await twinHandler.connect(operator).createTwin(twin);

let [exists, storedTwin] = await twinHandler.getTwin("666");
expect(exists).to.be.false;
expect(storedTwin.id).to.be.equal("0");

[exists, storedTwin] = await twinHandler.getTwin(nextTwinId);
expect(exists).to.be.true;
expect(storedTwin.id).to.be.equal(nextTwinId);
assert.notEqual(storedTwin.id, twin.id, "Twin Id is incorrect");
});

it("Should ignore twin id set by seller and use nextAccountId on twinIdsByTokenAddressAndBySeller lookup", async function () {
twin.id = "666";
twin.tokenType = TokenType.NonFungibleToken;
twin.tokenAddress = foreign721.address;
twin.amount = "0";
twin.tokenId = "1";
twin.supplyAvailable = "10";

// Approving the twinHandler contract to transfer seller's tokens
await foreign721.connect(operator).mint(twin.tokenId, twin.supplyAvailable);
await foreign721.connect(operator).setApprovalForAll(twinHandler.address, true);

const tx = await twinHandler.connect(operator).createTwin(twin);
const txReceipt = await tx.wait();

const [id] = getEvent(txReceipt, twinHandler, "TwinCreated");

// starting slot
const protocolLookupsSlot = keccak256(ethers.utils.toUtf8Bytes("boson.protocol.lookups"));
const protocolLookupsSlotNumber = ethers.BigNumber.from(protocolLookupsSlot);

// seller id mapping from twinIdsByTokenAddressAndBySeller
const firstMappingSlot = ethers.BigNumber.from(
getMappingStoragePosition(
protocolLookupsSlotNumber.add("23"),
ethers.BigNumber.from(seller.id).toNumber(),
paddingType.START
)
);

// token address mapping from twinIdsByTokenAddressAndBySeller
const secondMappingSlot = getMappingStoragePosition(
firstMappingSlot,
twin.tokenAddress.toLowerCase(),
paddingType.START
);

// first element of twinIds from twinIdsByTokenAddressAndBySeller
const firstIdSlot = keccak256(secondMappingSlot);
const twinId = await getStorageAt(protocolDiamond.address, firstIdSlot);

assert.equal(id, nextTwinId, "Twin Id is incorrect");
assert.equal(ethers.BigNumber.from(twinId), nextTwinId, "Twin Id is incorrect");
assert.notEqual(id, twin.id, "Twin Id is incorrect");
});

context("💔 Revert Reasons", async function () {
it("The twins region of protocol is paused", async function () {
// Pause the twins region of the protocol
Expand Down
2 changes: 1 addition & 1 deletion test/util/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -208,5 +208,5 @@ exports.prepareDataSignatureParameters = prepareDataSignatureParameters;
exports.calculateVoucherExpiry = calculateVoucherExpiry;
exports.calculateContractAddress = calculateContractAddress;
exports.applyPercentage = applyPercentage;
exports.paddingType = paddingType;
exports.getMappingStoragePosition = getMappingStoragePosition;
exports.paddingType = paddingType;

0 comments on commit b98377d

Please sign in to comment.