parent
0f6eb306ea
commit
a19e3f4198
|
@ -6,16 +6,12 @@ import "@openzeppelin/contracts/utils/math/Math.sol";
|
|||
import "@openzeppelin/contracts/utils/structs/EnumerableSet.sol";
|
||||
import "./Collateral.sol";
|
||||
import "./Proofs.sol";
|
||||
import "./libs/SetMap.sol";
|
||||
import "./libs/Utils.sol";
|
||||
|
||||
contract Marketplace is Collateral, Proofs {
|
||||
using EnumerableSet for EnumerableSet.Bytes32Set;
|
||||
using EnumerableSet for EnumerableSet.AddressSet;
|
||||
using Utils for EnumerableSet.Bytes32Set;
|
||||
using SetMap for SetMap.Bytes32SetMap;
|
||||
using SetMap for SetMap.AddressBytes32SetMap;
|
||||
using SetMap for SetMap.Bytes32AddressSetMap;
|
||||
|
||||
type RequestId is bytes32;
|
||||
type SlotId is bytes32;
|
||||
|
@ -382,17 +378,6 @@ contract Marketplace is Collateral, Proofs {
|
|||
}
|
||||
}
|
||||
|
||||
function _toRequestIds(SetMap.Bytes32SetMapKey[] memory array)
|
||||
private
|
||||
pure
|
||||
returns (RequestId[] memory result)
|
||||
{
|
||||
// solhint-disable-next-line no-inline-assembly
|
||||
assembly {
|
||||
result := array
|
||||
}
|
||||
}
|
||||
|
||||
function _toSlotIds(bytes32[] memory array)
|
||||
private
|
||||
pure
|
||||
|
@ -435,30 +420,6 @@ contract Marketplace is Collateral, Proofs {
|
|||
return EndId.wrap(RequestId.unwrap(requestId));
|
||||
}
|
||||
|
||||
function _toBytes32SetMapKey(RequestId requestId)
|
||||
internal
|
||||
pure
|
||||
returns (SetMap.Bytes32SetMapKey)
|
||||
{
|
||||
return SetMap.Bytes32SetMapKey.wrap(RequestId.unwrap(requestId));
|
||||
}
|
||||
|
||||
function _toAddressSetMapKey(address addr)
|
||||
internal
|
||||
pure
|
||||
returns (SetMap.AddressBytes32SetMapKey)
|
||||
{
|
||||
return SetMap.AddressBytes32SetMapKey.wrap(addr);
|
||||
}
|
||||
|
||||
function _toBytes32AddressSetMapKey(RequestId requestId)
|
||||
internal
|
||||
pure
|
||||
returns (SetMap.Bytes32AddressSetMapKey)
|
||||
{
|
||||
return SetMap.Bytes32AddressSetMapKey.wrap(RequestId.unwrap(requestId));
|
||||
}
|
||||
|
||||
function _notEqual(RequestId a, uint256 b) internal pure returns (bool) {
|
||||
return RequestId.unwrap(a) != bytes32(b);
|
||||
}
|
||||
|
|
|
@ -1,320 +0,0 @@
|
|||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity ^0.8.8;
|
||||
|
||||
import "@openzeppelin/contracts/utils/structs/EnumerableSet.sol";
|
||||
|
||||
library SetMap {
|
||||
using EnumerableSet for EnumerableSet.Bytes32Set;
|
||||
using EnumerableSet for EnumerableSet.AddressSet;
|
||||
|
||||
type Bytes32SetMapKey is bytes32;
|
||||
|
||||
struct Bytes32SetMap {
|
||||
mapping(Bytes32SetMapKey =>
|
||||
mapping(address =>
|
||||
mapping(uint8 =>
|
||||
EnumerableSet.Bytes32Set))) _values;
|
||||
mapping(Bytes32SetMapKey => uint8) _index;
|
||||
}
|
||||
|
||||
/// @notice Returns the EnumerableSet.Bytes32 containing the values for a key
|
||||
/// and address in an Bytes32SetMap
|
||||
/// @dev This is used internally to the library only. `.values()` should only
|
||||
/// be called on its return value in a view/pure function.
|
||||
/// @param map Bytes32SetMap to list values
|
||||
/// @param key key of the values to be listed
|
||||
/// @param addr address of the values to be listed
|
||||
/// @return bytes32[] array of bytes32 values
|
||||
function _set(Bytes32SetMap storage map,
|
||||
Bytes32SetMapKey key,
|
||||
address addr)
|
||||
private
|
||||
view
|
||||
returns (EnumerableSet.Bytes32Set storage)
|
||||
{
|
||||
uint8 id = map._index[key];
|
||||
return map._values[key][addr][id];
|
||||
}
|
||||
|
||||
/// @notice Lists all values for a key and address in an Bytes32SetMap
|
||||
/// @param map Bytes32SetMap to list values
|
||||
/// @param key key of the values to be listed
|
||||
/// @param addr address of the values to be listed
|
||||
/// @return bytes32[] array of bytes32 values
|
||||
function values(Bytes32SetMap storage map,
|
||||
Bytes32SetMapKey key,
|
||||
address addr)
|
||||
internal
|
||||
view
|
||||
returns (bytes32[] memory)
|
||||
{
|
||||
return _set(map, key, addr).values();
|
||||
}
|
||||
|
||||
/// @notice Adds a single value to an Bytes32SetMap
|
||||
/// @param map Bytes32SetMap to add the value to
|
||||
/// @param key key of the value to be added
|
||||
/// @param addr address of the value to be added
|
||||
/// @param value the value to be added
|
||||
/// @return true if the value was added to the set, that is if it was not
|
||||
/// already present.
|
||||
function add(Bytes32SetMap storage map,
|
||||
Bytes32SetMapKey key,
|
||||
address addr,
|
||||
bytes32 value)
|
||||
internal
|
||||
returns (bool)
|
||||
{
|
||||
return _set(map, key, addr).add(value);
|
||||
}
|
||||
|
||||
/// @notice Removes a single value from an Bytes32SetMap
|
||||
/// @param map Bytes32SetMap to remove the value from
|
||||
/// @param key key of the value to be removed
|
||||
/// @param addr address of the value to be removed
|
||||
/// @param value the value to be removed
|
||||
/// @return true if the value was removed from the set, that is if it was
|
||||
/// present.
|
||||
function remove(Bytes32SetMap storage map,
|
||||
Bytes32SetMapKey key,
|
||||
address addr,
|
||||
bytes32 value)
|
||||
internal
|
||||
returns (bool)
|
||||
{
|
||||
return _set(map, key, addr).remove(value);
|
||||
}
|
||||
|
||||
/// @notice Clears values for a key.
|
||||
/// @dev Does not clear the addresses for the key, simply updates an index
|
||||
/// such that the next time values for that key and address are
|
||||
/// retrieved, it will reference a new EnumerableSet.
|
||||
/// @param map Bytes32SetMap for which to clear values
|
||||
/// @param key key for which to clear values
|
||||
function clear(Bytes32SetMap storage map, Bytes32SetMapKey key)
|
||||
internal
|
||||
{
|
||||
map._index[key]++;
|
||||
}
|
||||
|
||||
/// @notice Returns the length of values for a key and address.
|
||||
/// @param map Bytes32SetMap for which to get length of values
|
||||
/// @param key key for which to get the length of values
|
||||
/// @param addr address for which to get the length of values
|
||||
function length(Bytes32SetMap storage map,
|
||||
Bytes32SetMapKey key,
|
||||
address addr)
|
||||
internal
|
||||
view
|
||||
returns (uint256)
|
||||
{
|
||||
return _set(map, key, addr).length();
|
||||
}
|
||||
|
||||
type AddressBytes32SetMapKey is address;
|
||||
|
||||
struct AddressBytes32SetMap {
|
||||
mapping(AddressBytes32SetMapKey =>
|
||||
mapping(uint8 =>
|
||||
EnumerableSet.Bytes32Set)) _values;
|
||||
mapping(AddressBytes32SetMapKey => uint8) _index;
|
||||
}
|
||||
|
||||
/// @notice Returns the EnumerableSet.Bytes32Set containing the values for a
|
||||
/// key in an AddressBytes32SetMap.
|
||||
/// @dev This is used internally to the library only. `.values()` should only
|
||||
/// be called on its return value in a view/pure function.
|
||||
/// @param map AddressBytes32SetMap containing the set to be retrieved.
|
||||
/// @param key key of the set to be retrieved.
|
||||
/// @return bytes32[] array of bytes32 values.
|
||||
function _set(AddressBytes32SetMap storage map,
|
||||
AddressBytes32SetMapKey key)
|
||||
private
|
||||
view
|
||||
returns (EnumerableSet.Bytes32Set storage)
|
||||
{
|
||||
uint8 id = map._index[key];
|
||||
return map._values[key][id];
|
||||
}
|
||||
|
||||
/// @notice Lists all values for a key in an AddressBytes32SetMap
|
||||
/// @param map AddressBytes32SetMap to list values
|
||||
/// @param key key of the values to be listed
|
||||
/// @return bytes32[] array of bytes32 values
|
||||
function values(AddressBytes32SetMap storage map, AddressBytes32SetMapKey key)
|
||||
internal
|
||||
view
|
||||
returns (bytes32[] memory)
|
||||
{
|
||||
return _set(map, key).values();
|
||||
}
|
||||
|
||||
/// @notice Adds a single value to an AddressBytes32SetMap
|
||||
/// @param map AddressBytes32SetMap to add the value to.
|
||||
/// @param key key of the value to be added.
|
||||
/// @param value the value to be added.
|
||||
/// @return true if the value was added to the set, that is if it was not
|
||||
/// already present.
|
||||
function add(AddressBytes32SetMap storage map,
|
||||
AddressBytes32SetMapKey key,
|
||||
bytes32 value)
|
||||
internal
|
||||
returns (bool)
|
||||
{
|
||||
return _set(map, key).add(value);
|
||||
}
|
||||
|
||||
/// @notice Removes a single value from an AddressBytes32SetMap
|
||||
/// @param map AddressBytes32SetMap to remove the value from
|
||||
/// @param key key of the value to be removed
|
||||
/// @param value the value to be removed
|
||||
/// @return true if the value was removed from the set, that is if it was
|
||||
/// present.
|
||||
function remove(AddressBytes32SetMap storage map,
|
||||
AddressBytes32SetMapKey key,
|
||||
bytes32 value)
|
||||
internal
|
||||
returns (bool)
|
||||
{
|
||||
return _set(map, key).remove(value);
|
||||
}
|
||||
|
||||
/// @notice Clears values for a key.
|
||||
/// @dev Updates an index such that the next time values for that key are
|
||||
/// retrieved, it will reference a new EnumerableSet.
|
||||
/// @param map AddressBytes32SetMap for which to clear values
|
||||
/// @param key key for which to clear values
|
||||
function clear(AddressBytes32SetMap storage map, AddressBytes32SetMapKey key)
|
||||
internal
|
||||
{
|
||||
map._index[key]++;
|
||||
}
|
||||
|
||||
type Bytes32AddressSetMapKey is bytes32;
|
||||
|
||||
struct Bytes32AddressSetMap {
|
||||
mapping(Bytes32AddressSetMapKey =>
|
||||
mapping(uint8 =>
|
||||
EnumerableSet.AddressSet)) _values;
|
||||
mapping(Bytes32AddressSetMapKey => uint8) _index;
|
||||
EnumerableSet.Bytes32Set _keys;
|
||||
}
|
||||
|
||||
/// @notice Returns the EnumerableSet.AddressSet containing the values for a
|
||||
/// key in an Bytes32AddressSetMap.
|
||||
/// @dev This is used internally to the library only. `.values()` should only
|
||||
/// be called on its return value in a view/pure function.
|
||||
/// @param map Bytes32AddressSetMap containing the set to be retrieved.
|
||||
/// @param key key of the set to be retrieved.
|
||||
/// @return bytes32[] array of bytes32 values.
|
||||
function _set(Bytes32AddressSetMap storage map,
|
||||
Bytes32AddressSetMapKey key)
|
||||
private
|
||||
view
|
||||
returns (EnumerableSet.AddressSet storage)
|
||||
{
|
||||
uint8 id = map._index[key];
|
||||
return map._values[key][id];
|
||||
}
|
||||
|
||||
/// @notice Lists all keys for an Bytes32AddressSetMap
|
||||
/// @param map Bytes32AddressSetMap to list keys
|
||||
/// @return bytes32[] array of bytes32 values
|
||||
function keys(Bytes32AddressSetMap storage map)
|
||||
internal
|
||||
view
|
||||
returns (EnumerableSet.Bytes32Set storage)
|
||||
{
|
||||
return map._keys;
|
||||
}
|
||||
|
||||
/// @notice Lists all values for a key in an Bytes32AddressSetMap
|
||||
/// @param map Bytes32AddressSetMap to list values
|
||||
/// @param key key of the values to be listed
|
||||
/// @return bytes32[] array of bytes32 values
|
||||
function values(Bytes32AddressSetMap storage map,
|
||||
Bytes32AddressSetMapKey key)
|
||||
internal
|
||||
view
|
||||
returns (address[] memory)
|
||||
{
|
||||
return _set(map, key).values();
|
||||
}
|
||||
|
||||
/// @notice Lists all values for a key in an Bytes32AddressSetMap
|
||||
/// @param map Bytes32AddressSetMap to list values
|
||||
/// @param key key of the values to be listed
|
||||
/// @return bytes32[] array of bytes32 values
|
||||
function contains(Bytes32AddressSetMap storage map,
|
||||
Bytes32AddressSetMapKey key,
|
||||
address addr)
|
||||
internal
|
||||
view
|
||||
returns (bool)
|
||||
{
|
||||
return _set(map, key).contains(addr);
|
||||
}
|
||||
|
||||
/// @notice Returns the length of values for a key.
|
||||
/// @param map Bytes32AddressSetMap for which to get length
|
||||
/// @param key key for which to get the length of values
|
||||
function length(Bytes32AddressSetMap storage map,
|
||||
Bytes32AddressSetMapKey key)
|
||||
internal
|
||||
view
|
||||
returns (uint256)
|
||||
{
|
||||
return _set(map, key).length();
|
||||
}
|
||||
|
||||
/// @notice Adds a single value to an Bytes32AddressSetMap
|
||||
/// @param map Bytes32AddressSetMap to add the value to.
|
||||
/// @param key key of the value to be added.
|
||||
/// @param value the value to be added.
|
||||
/// @return true if the value was added to the set, that is if it was not
|
||||
/// already present.
|
||||
function add(Bytes32AddressSetMap storage map,
|
||||
Bytes32AddressSetMapKey key,
|
||||
address value)
|
||||
internal
|
||||
returns (bool)
|
||||
{
|
||||
bool success = _set(map, key).add(value);
|
||||
if (success) {
|
||||
map._keys.add(Bytes32AddressSetMapKey.unwrap(key));
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
/// @notice Removes a single value from an Bytes32AddressSetMap
|
||||
/// @param map Bytes32AddressSetMap to remove the value from
|
||||
/// @param key key of the value to be removed
|
||||
/// @param value the value to be removed
|
||||
/// @return true if the value was removed from the set, that is if it was
|
||||
/// present.
|
||||
function remove(Bytes32AddressSetMap storage map,
|
||||
Bytes32AddressSetMapKey key,
|
||||
address value)
|
||||
internal
|
||||
returns (bool)
|
||||
{
|
||||
EnumerableSet.AddressSet storage set = _set(map, key);
|
||||
bool success = _set(map, key).remove(value);
|
||||
if (success && set.length() == 0) {
|
||||
map._keys.remove(Bytes32AddressSetMapKey.unwrap(key));
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
/// @notice Clears values for a key.
|
||||
/// @dev Updates an index such that the next time values for that key are
|
||||
/// retrieved, it will reference a new EnumerableSet.
|
||||
/// @param map Bytes32AddressSetMap for which to clear values
|
||||
/// @param key key for which to clear values
|
||||
function clear(Bytes32AddressSetMap storage map, Bytes32AddressSetMapKey key)
|
||||
internal
|
||||
{
|
||||
map._index[key]++;
|
||||
map._keys.remove(Bytes32AddressSetMapKey.unwrap(key));
|
||||
}
|
||||
}
|
|
@ -1,157 +0,0 @@
|
|||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity ^0.8.0;
|
||||
|
||||
import "./SetMap.sol";
|
||||
|
||||
// exposes public functions for testing
|
||||
contract TestBytes32SetMap {
|
||||
using SetMap for SetMap.Bytes32SetMap;
|
||||
|
||||
event OperationResult(bool result);
|
||||
|
||||
SetMap.Bytes32SetMap private _set;
|
||||
|
||||
function values(SetMap.Bytes32SetMapKey key,
|
||||
address addr)
|
||||
public
|
||||
view
|
||||
returns (bytes32[] memory)
|
||||
{
|
||||
return _set.values(key, addr);
|
||||
}
|
||||
|
||||
function add(SetMap.Bytes32SetMapKey key,
|
||||
address addr,
|
||||
bytes32 value)
|
||||
public
|
||||
{
|
||||
bool result = _set.add(key, addr, value);
|
||||
emit OperationResult(result);
|
||||
}
|
||||
|
||||
function remove(SetMap.Bytes32SetMapKey key,
|
||||
address addr,
|
||||
bytes32 value)
|
||||
public
|
||||
{
|
||||
bool result = _set.remove(key, addr, value);
|
||||
emit OperationResult(result);
|
||||
}
|
||||
|
||||
function clear(SetMap.Bytes32SetMapKey key)
|
||||
public
|
||||
{
|
||||
_set.clear(key);
|
||||
}
|
||||
|
||||
function length(SetMap.Bytes32SetMapKey key,
|
||||
address addr)
|
||||
public
|
||||
view
|
||||
returns (uint256)
|
||||
{
|
||||
return _set.length(key, addr);
|
||||
}
|
||||
}
|
||||
|
||||
contract TestAddressBytes32SetMap {
|
||||
using SetMap for SetMap.AddressBytes32SetMap;
|
||||
|
||||
event OperationResult(bool result);
|
||||
|
||||
SetMap.AddressBytes32SetMap private _set;
|
||||
|
||||
function values(SetMap.AddressBytes32SetMapKey key)
|
||||
public
|
||||
view
|
||||
returns (bytes32[] memory)
|
||||
{
|
||||
return _set.values(key);
|
||||
}
|
||||
|
||||
function add(SetMap.AddressBytes32SetMapKey key,
|
||||
bytes32 value)
|
||||
public
|
||||
{
|
||||
bool result = _set.add(key, value);
|
||||
emit OperationResult(result);
|
||||
}
|
||||
|
||||
function remove(SetMap.AddressBytes32SetMapKey key,
|
||||
bytes32 value)
|
||||
public
|
||||
{
|
||||
bool result = _set.remove(key, value);
|
||||
emit OperationResult(result);
|
||||
}
|
||||
|
||||
function clear(SetMap.AddressBytes32SetMapKey key)
|
||||
public
|
||||
{
|
||||
_set.clear(key);
|
||||
}
|
||||
}
|
||||
|
||||
contract TestBytes32AddressSetMap {
|
||||
using EnumerableSet for EnumerableSet.Bytes32Set;
|
||||
using SetMap for SetMap.Bytes32AddressSetMap;
|
||||
|
||||
event OperationResult(bool result);
|
||||
|
||||
SetMap.Bytes32AddressSetMap private _set;
|
||||
|
||||
function keys()
|
||||
view
|
||||
public
|
||||
returns (bytes32[] memory)
|
||||
{
|
||||
return _set._keys.values();
|
||||
}
|
||||
|
||||
function values(SetMap.Bytes32AddressSetMapKey key)
|
||||
public
|
||||
view
|
||||
returns (address[] memory)
|
||||
{
|
||||
return _set.values(key);
|
||||
}
|
||||
|
||||
function contains(SetMap.Bytes32AddressSetMapKey key,
|
||||
address addr)
|
||||
public
|
||||
view
|
||||
returns (bool)
|
||||
{
|
||||
return _set.contains(key, addr);
|
||||
}
|
||||
|
||||
function length(SetMap.Bytes32AddressSetMapKey key)
|
||||
public
|
||||
view
|
||||
returns (uint256)
|
||||
{
|
||||
return _set.length(key);
|
||||
}
|
||||
|
||||
function add(SetMap.Bytes32AddressSetMapKey key,
|
||||
address value)
|
||||
public
|
||||
{
|
||||
bool result = _set.add(key, value);
|
||||
emit OperationResult(result);
|
||||
}
|
||||
|
||||
function remove(SetMap.Bytes32AddressSetMapKey key,
|
||||
address value)
|
||||
public
|
||||
{
|
||||
bool result = _set.remove(key, value);
|
||||
emit OperationResult(result);
|
||||
}
|
||||
|
||||
function clear(SetMap.Bytes32AddressSetMapKey key)
|
||||
public
|
||||
{
|
||||
_set.clear(key);
|
||||
}
|
||||
}
|
|
@ -1,207 +0,0 @@
|
|||
const { ethers } = require("hardhat")
|
||||
const { expect } = require("chai")
|
||||
const { hexlify, randomBytes } = ethers.utils
|
||||
const { exampleAddress } = require("./examples")
|
||||
|
||||
describe("SetMap", function () {
|
||||
let account
|
||||
let key
|
||||
let value
|
||||
let contract
|
||||
|
||||
describe("Bytes32SetMap", function () {
|
||||
beforeEach(async function () {
|
||||
let Bytes32SetMap = await ethers.getContractFactory("TestBytes32SetMap")
|
||||
contract = await Bytes32SetMap.deploy()
|
||||
;[account] = await ethers.getSigners()
|
||||
key = randomBytes(32)
|
||||
value = randomBytes(32)
|
||||
})
|
||||
|
||||
it("starts empty", async function () {
|
||||
await expect(await contract.values(key, account.address)).to.deep.equal(
|
||||
[]
|
||||
)
|
||||
})
|
||||
|
||||
it("adds a key/address and value", async function () {
|
||||
await expect(contract.add(key, account.address, value))
|
||||
.to.emit(contract, "OperationResult")
|
||||
.withArgs(true)
|
||||
await expect(await contract.values(key, account.address)).to.deep.equal([
|
||||
hexlify(value),
|
||||
])
|
||||
})
|
||||
|
||||
it("removes a value for key/address", async function () {
|
||||
let value1 = randomBytes(32)
|
||||
await contract.add(key, account.address, value)
|
||||
await contract.add(key, account.address, value1)
|
||||
await expect(contract.remove(key, account.address, value))
|
||||
.to.emit(contract, "OperationResult")
|
||||
.withArgs(true)
|
||||
await expect(await contract.values(key, account.address)).to.deep.equal([
|
||||
hexlify(value1),
|
||||
])
|
||||
})
|
||||
|
||||
it("clears all values for a key", async function () {
|
||||
let key1 = randomBytes(32)
|
||||
let value1 = randomBytes(32)
|
||||
let value2 = randomBytes(32)
|
||||
await contract.add(key, account.address, value)
|
||||
await contract.add(key, account.address, value1)
|
||||
await contract.add(key, account.address, value2)
|
||||
await contract.add(key1, account.address, value)
|
||||
await expect(contract.clear(key))
|
||||
await expect(await contract.values(key, account.address)).to.deep.equal(
|
||||
[]
|
||||
)
|
||||
await expect(await contract.values(key1, account.address)).to.deep.equal([
|
||||
hexlify(value),
|
||||
])
|
||||
})
|
||||
|
||||
it("gets the length of values for a key/address", async function () {
|
||||
let value1 = randomBytes(32)
|
||||
let value2 = randomBytes(32)
|
||||
await contract.add(key, account.address, value)
|
||||
await contract.add(key, account.address, value1)
|
||||
await contract.add(key, account.address, value2)
|
||||
await expect(await contract.length(key, account.address)).to.equal(3)
|
||||
})
|
||||
})
|
||||
|
||||
describe("AddressBytes32SetMap", function () {
|
||||
beforeEach(async function () {
|
||||
let AddressBytes32SetMap = await ethers.getContractFactory(
|
||||
"TestAddressBytes32SetMap"
|
||||
)
|
||||
contract = await AddressBytes32SetMap.deploy()
|
||||
;[account, account1] = await ethers.getSigners()
|
||||
key = account.address
|
||||
value = randomBytes(32)
|
||||
})
|
||||
|
||||
it("starts empty", async function () {
|
||||
await expect(await contract.values(key)).to.deep.equal([])
|
||||
})
|
||||
|
||||
it("adds a key/address and value", async function () {
|
||||
await expect(contract.add(key, value))
|
||||
.to.emit(contract, "OperationResult")
|
||||
.withArgs(true)
|
||||
await expect(await contract.values(key)).to.deep.equal([hexlify(value)])
|
||||
})
|
||||
|
||||
it("removes a value for key/address", async function () {
|
||||
let value1 = randomBytes(32)
|
||||
await contract.add(key, value)
|
||||
await contract.add(key, value1)
|
||||
await expect(contract.remove(key, value))
|
||||
.to.emit(contract, "OperationResult")
|
||||
.withArgs(true)
|
||||
await expect(await contract.values(key)).to.deep.equal([hexlify(value1)])
|
||||
})
|
||||
|
||||
it("clears all values for a key", async function () {
|
||||
let key1 = account1.address
|
||||
let value1 = randomBytes(32)
|
||||
let value2 = randomBytes(32)
|
||||
await contract.add(key, value)
|
||||
await contract.add(key, value1)
|
||||
await contract.add(key, value2)
|
||||
await contract.add(key1, value)
|
||||
await expect(contract.clear(key))
|
||||
await expect(await contract.values(key)).to.deep.equal([])
|
||||
await expect(await contract.values(key1)).to.deep.equal([hexlify(value)])
|
||||
})
|
||||
})
|
||||
|
||||
describe("Bytes32AddressSetMap", function () {
|
||||
beforeEach(async function () {
|
||||
let Bytes32AddressSetMap = await ethers.getContractFactory(
|
||||
"TestBytes32AddressSetMap"
|
||||
)
|
||||
contract = await Bytes32AddressSetMap.deploy()
|
||||
;[account] = await ethers.getSigners()
|
||||
key = randomBytes(32)
|
||||
value = exampleAddress()
|
||||
})
|
||||
|
||||
it("starts empty", async function () {
|
||||
await expect(await contract.values(key)).to.deep.equal([])
|
||||
})
|
||||
|
||||
it("adds a key/address and value", async function () {
|
||||
await expect(contract.add(key, value))
|
||||
.to.emit(contract, "OperationResult")
|
||||
.withArgs(true)
|
||||
await expect(await contract.values(key)).to.deep.equal([value])
|
||||
})
|
||||
|
||||
it("returns list of keys", async function () {
|
||||
let key1 = randomBytes(32)
|
||||
let value1 = exampleAddress()
|
||||
await contract.add(key, value)
|
||||
await contract.add(key, value1)
|
||||
await contract.add(key1, value)
|
||||
await contract.add(key1, value1)
|
||||
await expect(await contract.keys()).to.deep.equal([
|
||||
hexlify(key),
|
||||
hexlify(key1),
|
||||
])
|
||||
await contract.remove(key1, value)
|
||||
await expect(await contract.keys()).to.deep.equal([
|
||||
hexlify(key),
|
||||
hexlify(key1),
|
||||
])
|
||||
await contract.remove(key1, value1)
|
||||
await expect(await contract.keys()).to.deep.equal([hexlify(key)])
|
||||
await contract.clear(key)
|
||||
await expect(await contract.keys()).to.deep.equal([])
|
||||
})
|
||||
|
||||
it("contains a key/value pair", async function () {
|
||||
let key1 = randomBytes(32)
|
||||
let value1 = exampleAddress()
|
||||
await contract.add(key, value)
|
||||
await contract.add(key1, value1)
|
||||
await expect(await contract.contains(key, value)).to.equal(true)
|
||||
await expect(await contract.contains(key1, value1)).to.equal(true)
|
||||
await expect(await contract.contains(key1, value)).to.equal(false)
|
||||
})
|
||||
|
||||
it("removes a value for key/address", async function () {
|
||||
let value1 = exampleAddress()
|
||||
await contract.add(key, value)
|
||||
await contract.add(key, value1)
|
||||
await expect(contract.remove(key, value))
|
||||
.to.emit(contract, "OperationResult")
|
||||
.withArgs(true)
|
||||
await expect(await contract.values(key)).to.deep.equal([value1])
|
||||
})
|
||||
|
||||
it("clears all values for a key", async function () {
|
||||
let key1 = randomBytes(32)
|
||||
let value1 = exampleAddress()
|
||||
let value2 = exampleAddress()
|
||||
await contract.add(key, value)
|
||||
await contract.add(key, value1)
|
||||
await contract.add(key, value2)
|
||||
await contract.add(key1, value)
|
||||
await expect(contract.clear(key))
|
||||
await expect(await contract.values(key)).to.deep.equal([])
|
||||
await expect(await contract.values(key1)).to.deep.equal([value])
|
||||
})
|
||||
|
||||
it("gets the length of values for a key/address", async function () {
|
||||
let value1 = exampleAddress()
|
||||
let value2 = exampleAddress()
|
||||
await contract.add(key, value)
|
||||
await contract.add(key, value1)
|
||||
await contract.add(key, value2)
|
||||
await expect(await contract.length(key)).to.equal(3)
|
||||
})
|
||||
})
|
||||
})
|
Loading…
Reference in New Issue