Skip to content

Commit a79ce8c

Browse files
committed
Use storage slot for upgradeable contracts
1 parent 9770473 commit a79ce8c

19 files changed

+5112
-4895
lines changed

src/contracts/mocks/ERC1155MetadataUpgradeableMock.sol

+1-1
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,6 @@ contract ERC1155MetadataUpgradeableMockV2 is ERC1155MetadataUpgradeableMock {
7272
}
7373

7474
function uri(uint256 _id) public override view returns (string memory) {
75-
return string(abi.encodePacked(baseURI, _uint2str(idMapping[_id]))); // Removes .json extension, swaps ids
75+
return string(abi.encodePacked(baseURI(), _uint2str(idMapping[_id]))); // Removes .json extension, swaps ids
7676
}
7777
}

src/contracts/tokens/ERC1155/ERC1155Meta.sol

+4-3
Original file line numberDiff line numberDiff line change
@@ -294,12 +294,13 @@ contract ERC1155Meta is ERC1155, SignatureValidator {
294294
// Complete data to pass to signer verifier
295295
bytes memory fullData = abi.encodePacked(_encMembers, nonce, signedData);
296296

297-
//Update signature nonce
297+
// Verify if _from is the signer
298+
require(isValidSignature(_signer, hash, fullData, sig), "ERC1155Meta#_signatureValidation: INVALID_SIGNATURE");
299+
300+
// Update signature nonce
298301
nonces[_signer] = nonce + 1;
299302
emit NonceChange(_signer, nonce + 1);
300303

301-
// Verify if _from is the signer
302-
require(isValidSignature(_signer, hash, fullData, sig), "ERC1155Meta#_signatureValidation: INVALID_SIGNATURE");
303304
return signedData;
304305
}
305306

src/contracts/tokens/ERC1155PackedBalanceUpgradeable/ERC1155MetaPackedBalanceUpgradeable.sol

+28-8
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import "../../interfaces/IERC20.sol";
66
import "../../interfaces/IERC1155.sol";
77
import "../../utils/LibBytes.sol";
88
import "../../utils/SignatureValidator.sol";
9-
9+
import '../../utils/StorageSlot.sol';
1010

1111
/**
1212
* @dev ERC-1155 with native metatransaction methods. These additional functions allow users
@@ -45,7 +45,7 @@ contract ERC1155MetaPackedBalanceUpgradeable is ERC1155PackedBalanceUpgradeable,
4545
}
4646

4747
// Signature nonce per address
48-
mapping (address => uint256) internal nonces;
48+
bytes32 constant private _NONCES_SLOT_KEY = keccak256("0xsequence.ERC1155MetaPackedBalanceUpgradeable.nonces");
4949

5050

5151
/***********************************|
@@ -227,7 +227,7 @@ contract ERC1155MetaPackedBalanceUpgradeable is ERC1155PackedBalanceUpgradeable,
227227
);
228228

229229
// Update operator status
230-
operators[_owner][_operator] = _approved;
230+
_setOperator(_owner, _operator, _approved);
231231

232232
// Emit event
233233
emit ApprovalForAll(_owner, _operator, _approved);
@@ -284,8 +284,8 @@ contract ERC1155MetaPackedBalanceUpgradeable is ERC1155PackedBalanceUpgradeable,
284284
(sig, signedData) = abi.decode(_sigData, (bytes, bytes));
285285

286286
// Get current nonce and nonce used for signature
287-
uint256 currentNonce = nonces[_signer]; // Lowest valid nonce for signer
288-
uint256 nonce = uint256(sig.readBytes32(65)); // Nonce passed in the signature object
287+
uint256 currentNonce = _getNonce(_signer); // Lowest valid nonce for signer
288+
uint256 nonce = uint256(sig.readBytes32(65)); // Nonce passed in the signature object
289289

290290
// Verify if nonce is valid
291291
require(
@@ -300,8 +300,9 @@ contract ERC1155MetaPackedBalanceUpgradeable is ERC1155PackedBalanceUpgradeable,
300300
bytes memory fullData = abi.encodePacked(_encMembers, nonce, signedData);
301301

302302
//Update signature nonce
303-
nonces[_signer] = nonce + 1;
304-
emit NonceChange(_signer, nonce + 1);
303+
nonce++;
304+
_setNonce(_signer, nonce);
305+
emit NonceChange(_signer, nonce);
305306

306307
// Verify if _from is the signer
307308
require(isValidSignature(_signer, hash, fullData, sig), "ERC1155MetaPackedBalance#_signatureValidation: INVALID_SIGNATURE");
@@ -315,7 +316,26 @@ contract ERC1155MetaPackedBalanceUpgradeable is ERC1155PackedBalanceUpgradeable,
315316
function getNonce(address _signer)
316317
public view returns (uint256 nonce)
317318
{
318-
return nonces[_signer];
319+
return _getNonce(_signer);
320+
}
321+
322+
/**
323+
* @notice Returns the current nonce associated with a given address
324+
* @param _signer Address to query signature nonce for
325+
*/
326+
function _getNonce(address _signer)
327+
internal view returns (uint256 nonce)
328+
{
329+
return StorageSlot.getUint256Slot(keccak256(abi.encodePacked(_NONCES_SLOT_KEY, _signer))).value;
330+
}
331+
332+
/**
333+
* @notice Sets the nonce associated with a given address
334+
* @param _signer Address to set signature nonce for
335+
* @param _nonce Nonce value to set
336+
*/
337+
function _setNonce(address _signer, uint256 _nonce) internal {
338+
StorageSlot.getUint256Slot(keccak256(abi.encodePacked(_NONCES_SLOT_KEY, _signer))).value = _nonce;
319339
}
320340

321341

src/contracts/tokens/ERC1155PackedBalanceUpgradeable/ERC1155MintBurnPackedBalanceUpgradeable.sol

+4-4
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ contract ERC1155MintBurnPackedBalanceUpgradeable is ERC1155PackedBalanceUpgradea
5151
(uint256 bin, uint256 index) = getIDBinIndex(_ids[0]);
5252

5353
// Balance for current bin in memory (initialized with first transfer)
54-
uint256 balTo = _viewUpdateBinValue(balances[_to][bin], index, _amounts[0], Operations.Add);
54+
uint256 balTo = _viewUpdateBinValue(_getBalance(_to, bin), index, _amounts[0], Operations.Add);
5555

5656
// Number of transfer to execute
5757
uint256 nTransfer = _ids.length;
@@ -65,8 +65,8 @@ contract ERC1155MintBurnPackedBalanceUpgradeable is ERC1155PackedBalanceUpgradea
6565
// If new bin
6666
if (bin != lastBin) {
6767
// Update storage balance of previous bin
68-
balances[_to][lastBin] = balTo;
69-
balTo = balances[_to][bin];
68+
_setBalance(_to, lastBin, balTo);
69+
balTo = _getBalance(_to, bin);
7070

7171
// Bin will be the most recent bin
7272
lastBin = bin;
@@ -77,7 +77,7 @@ contract ERC1155MintBurnPackedBalanceUpgradeable is ERC1155PackedBalanceUpgradea
7777
}
7878

7979
// Update storage of the last bin visited
80-
balances[_to][bin] = balTo;
80+
_setBalance(_to, bin, balTo);
8181
}
8282

8383
// //Emit event

src/contracts/tokens/ERC1155PackedBalanceUpgradeable/ERC1155PackedBalanceUpgradeable.sol

+37-16
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import "../../interfaces/IERC1155.sol";
66
import "../../utils/Address.sol";
77
import "../../utils/ContextUpgradeable.sol";
88
import "../../utils/ERC165.sol";
9+
import '../../utils/StorageSlot.sol';
910

1011
/**
1112
* @dev Implementation of Multi-Token Standard contract. This implementation of the ERC-1155 standard
@@ -35,10 +36,10 @@ contract ERC1155PackedBalanceUpgradeable is ContextUpgradeable, IERC1155, ERC165
3536
enum Operations { Add, Sub }
3637

3738
// Token IDs balances ; balances[address][id] => balance (using array instead of mapping for efficiency)
38-
mapping (address => mapping(uint256 => uint256)) internal balances;
39+
bytes32 constant private _BALANCES_SLOT_KEY = keccak256("0xsequence.ERC1155PackedBalanceUpgradeable.balances");
3940

4041
// Operators
41-
mapping (address => mapping(address => bool)) internal operators;
42+
bytes32 constant private _OPERATORS_SLOT_KEY = keccak256("0xsequence.ERC1155PackedBalanceUpgradeable.operators");
4243

4344

4445
/***********************************|
@@ -140,8 +141,8 @@ contract ERC1155PackedBalanceUpgradeable is ContextUpgradeable, IERC1155, ERC165
140141
(uint256 bin, uint256 index) = getIDBinIndex(_ids[0]);
141142

142143
// Balance for current bin in memory (initialized with first transfer)
143-
uint256 balFrom = _viewUpdateBinValue(balances[_from][bin], index, _amounts[0], Operations.Sub);
144-
uint256 balTo = _viewUpdateBinValue(balances[_to][bin], index, _amounts[0], Operations.Add);
144+
uint256 balFrom = _viewUpdateBinValue(_getBalance(_from, bin), index, _amounts[0], Operations.Sub);
145+
uint256 balTo = _viewUpdateBinValue(_getBalance(_to, bin), index, _amounts[0], Operations.Add);
145146

146147
// Last bin updated
147148
uint256 lastBin = bin;
@@ -152,11 +153,11 @@ contract ERC1155PackedBalanceUpgradeable is ContextUpgradeable, IERC1155, ERC165
152153
// If new bin
153154
if (bin != lastBin) {
154155
// Update storage balance of previous bin
155-
balances[_from][lastBin] = balFrom;
156-
balances[_to][lastBin] = balTo;
156+
_setBalance(_from, lastBin, balFrom);
157+
_setBalance(_to, lastBin, balTo);
157158

158-
balFrom = balances[_from][bin];
159-
balTo = balances[_to][bin];
159+
balFrom = _getBalance(_from, bin);
160+
balTo = _getBalance(_to, bin);
160161

161162
// Bin will be the most recent bin
162163
lastBin = bin;
@@ -168,8 +169,8 @@ contract ERC1155PackedBalanceUpgradeable is ContextUpgradeable, IERC1155, ERC165
168169
}
169170

170171
// Update storage of the last bin visited
171-
balances[_from][bin] = balFrom;
172-
balances[_to][bin] = balTo;
172+
_setBalance(_from, bin, balFrom);
173+
_setBalance(_to, bin, balTo);
173174

174175
// If transfer to self, just make sure all amounts are valid
175176
} else {
@@ -209,7 +210,7 @@ contract ERC1155PackedBalanceUpgradeable is ContextUpgradeable, IERC1155, ERC165
209210
external override
210211
{
211212
// Update operator status
212-
operators[_msgSender()][_operator] = _approved;
213+
_setOperator(_msgSender(), _operator, _approved);
213214
emit ApprovalForAll(_msgSender(), _operator, _approved);
214215
}
215216

@@ -222,7 +223,7 @@ contract ERC1155PackedBalanceUpgradeable is ContextUpgradeable, IERC1155, ERC165
222223
function isApprovedForAll(address _owner, address _operator)
223224
public override view returns (bool isOperator)
224225
{
225-
return operators[_owner][_operator];
226+
return _getOperator(_owner, _operator);
226227
}
227228

228229

@@ -244,7 +245,7 @@ contract ERC1155PackedBalanceUpgradeable is ContextUpgradeable, IERC1155, ERC165
244245

245246
//Get bin and index of _id
246247
(bin, index) = getIDBinIndex(_id);
247-
return getValueInBin(balances[_owner][bin], index);
248+
return getValueInBin(_getBalance(_owner, bin), index);
248249
}
249250

250251
/**
@@ -261,7 +262,7 @@ contract ERC1155PackedBalanceUpgradeable is ContextUpgradeable, IERC1155, ERC165
261262

262263
// First values
263264
(uint256 bin, uint256 index) = getIDBinIndex(_ids[0]);
264-
uint256 balance_bin = balances[_owners[0]][bin];
265+
uint256 balance_bin = _getBalance(_owners[0], bin);
265266
uint256 last_bin = bin;
266267

267268
// Initialization
@@ -274,7 +275,7 @@ contract ERC1155PackedBalanceUpgradeable is ContextUpgradeable, IERC1155, ERC165
274275

275276
// SLOAD if bin changed for the same owner or if owner changed
276277
if (bin != last_bin || _owners[i-1] != _owners[i]) {
277-
balance_bin = balances[_owners[i]][bin];
278+
balance_bin = _getBalance(_owners[i], bin);
278279
last_bin = bin;
279280
}
280281

@@ -308,7 +309,7 @@ contract ERC1155PackedBalanceUpgradeable is ContextUpgradeable, IERC1155, ERC165
308309
(bin, index) = getIDBinIndex(_id);
309310

310311
// Update balance
311-
balances[_address][bin] = _viewUpdateBinValue(balances[_address][bin], index, _amount, _operation);
312+
_setBalance(_address, bin, _viewUpdateBinValue(_getBalance(_address, bin), index, _amount, _operation));
312313
}
313314

314315
/**
@@ -379,6 +380,26 @@ contract ERC1155PackedBalanceUpgradeable is ContextUpgradeable, IERC1155, ERC165
379380
return (_binValues >> rightShift) & mask;
380381
}
381382

383+
/***********************************|
384+
| Storage Functions |
385+
|__________________________________*/
386+
387+
function _getBalance(address _owner, uint256 _id) internal view returns (uint256) {
388+
return StorageSlot.getUint256Slot(keccak256(abi.encodePacked(_BALANCES_SLOT_KEY, _owner, _id))).value;
389+
}
390+
391+
function _setBalance(address _owner, uint256 _id, uint256 _balance) internal {
392+
StorageSlot.getUint256Slot(keccak256(abi.encodePacked(_BALANCES_SLOT_KEY, _owner, _id))).value = _balance;
393+
}
394+
395+
function _getOperator(address _owner, address _operator) internal view returns (bool) {
396+
return StorageSlot.getBooleanSlot(keccak256(abi.encodePacked(_OPERATORS_SLOT_KEY, _owner, _operator))).value;
397+
}
398+
399+
function _setOperator(address _owner, address _operator, bool _approved) internal {
400+
StorageSlot.getBooleanSlot(keccak256(abi.encodePacked(_OPERATORS_SLOT_KEY, _owner, _operator))).value = _approved;
401+
}
402+
382403

383404
/***********************************|
384405
| ERC165 Functions |

src/contracts/tokens/ERC1155Upgradeable/ERC1155MetaUpgradeable.sol

+31-10
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import "../../interfaces/IERC20.sol";
66
import "../../interfaces/IERC1155.sol";
77
import "../../utils/LibBytes.sol";
88
import "../../utils/SignatureValidator.sol";
9+
import '../../utils/StorageSlot.sol';
910

1011
/**
1112
* @dev ERC-1155 with native metatransaction methods. These additional functions allow users
@@ -41,8 +42,7 @@ contract ERC1155MetaUpgradeable is ERC1155Upgradeable, SignatureValidator {
4142
}
4243

4344
// Signature nonce per address
44-
mapping (address => uint256) internal nonces;
45-
45+
bytes32 constant private _NONCES_SLOT_KEY = keccak256("0xsequence.ERC1155MetaUpgradeable.nonces");
4646

4747
/***********************************|
4848
| Events |
@@ -223,7 +223,7 @@ contract ERC1155MetaUpgradeable is ERC1155Upgradeable, SignatureValidator {
223223
);
224224

225225
// Update operator status
226-
operators[_owner][_operator] = _approved;
226+
_setOperator(_owner, _operator, _approved);
227227

228228
// Emit event
229229
emit ApprovalForAll(_owner, _operator, _approved);
@@ -279,8 +279,8 @@ contract ERC1155MetaUpgradeable is ERC1155Upgradeable, SignatureValidator {
279279
(sig, signedData) = abi.decode(_sigData, (bytes, bytes));
280280

281281
// Get current nonce and nonce used for signature
282-
uint256 currentNonce = nonces[_signer]; // Lowest valid nonce for signer
283-
uint256 nonce = uint256(sig.readBytes32(65)); // Nonce passed in the signature object
282+
uint256 currentNonce = _getNonce(_signer); // Lowest valid nonce for signer
283+
uint256 nonce = uint256(sig.readBytes32(65)); // Nonce passed in the signature object
284284

285285
// Verify if nonce is valid
286286
require(
@@ -294,12 +294,14 @@ contract ERC1155MetaUpgradeable is ERC1155Upgradeable, SignatureValidator {
294294
// Complete data to pass to signer verifier
295295
bytes memory fullData = abi.encodePacked(_encMembers, nonce, signedData);
296296

297-
//Update signature nonce
298-
nonces[_signer] = nonce + 1;
299-
emit NonceChange(_signer, nonce + 1);
300-
301297
// Verify if _from is the signer
302298
require(isValidSignature(_signer, hash, fullData, sig), "ERC1155Meta#_signatureValidation: INVALID_SIGNATURE");
299+
300+
// Update signature nonce
301+
nonce++;
302+
_setNonce(_signer, nonce);
303+
emit NonceChange(_signer, nonce);
304+
303305
return signedData;
304306
}
305307

@@ -310,7 +312,26 @@ contract ERC1155MetaUpgradeable is ERC1155Upgradeable, SignatureValidator {
310312
function getNonce(address _signer)
311313
public view returns (uint256 nonce)
312314
{
313-
return nonces[_signer];
315+
return _getNonce(_signer);
316+
}
317+
318+
/**
319+
* @notice Returns the current nonce associated with a given address
320+
* @param _signer Address to query signature nonce for
321+
*/
322+
function _getNonce(address _signer)
323+
internal view returns (uint256 nonce)
324+
{
325+
return StorageSlot.getUint256Slot(keccak256(abi.encodePacked(_NONCES_SLOT_KEY, _signer))).value;
326+
}
327+
328+
/**
329+
* @notice Sets the nonce associated with a given address
330+
* @param _signer Address to set signature nonce for
331+
* @param _nonce Nonce value to set
332+
*/
333+
function _setNonce(address _signer, uint256 _nonce) internal {
334+
StorageSlot.getUint256Slot(keccak256(abi.encodePacked(_NONCES_SLOT_KEY, _signer))).value = _nonce;
314335
}
315336

316337

0 commit comments

Comments
 (0)