Skip to content

Commit

Permalink
chore(release): 2.3.1 (#165)
Browse files Browse the repository at this point in the history
* feat: added support for call value (#142)

Added functionality:
- `expect(myFake.myFunction).to.have.been.calledWithValue(1234);`
- `expect(myFake.myFunction.getCall(0).value).to.eq(1);`

* feat: arrays support for setVariable (#144)

* feat: update ethereumjs vm and hardhat (#155)

* fix: bug with usage of padNumHexSlotValue (#161)

Co-authored-by: 0xOneTony <[email protected]>
  • Loading branch information
0xGorilla and 0xOneTony authored Oct 21, 2022
1 parent f2f114b commit 201ba01
Show file tree
Hide file tree
Showing 7 changed files with 54 additions and 42 deletions.
17 changes: 17 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,23 @@

All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.

### [2.3.1](https://github.com/defi-wonderland/smock/compare/v2.1.0...v2.3.1) (2022-09-28)


### Features

* added support for call value ([#142](https://github.com/defi-wonderland/smock/issues/142)) ([3c2b80b](https://github.com/defi-wonderland/smock/commit/3c2b80b72fe146634b999df5b9bb9ef5ffc27508))
* arrays support for setVariable ([#144](https://github.com/defi-wonderland/smock/issues/144)) ([91a7aad](https://github.com/defi-wonderland/smock/commit/91a7aadf0cfa14ba52edb98c15fa0d38562fef39))
* return hardhat errors on factory failures ([#125](https://github.com/defi-wonderland/smock/issues/125)) ([3b626a3](https://github.com/defi-wonderland/smock/commit/3b626a3891c07ba224d2f12386bae95522843e2b))
* update ethereumjs vm and hardhat ([#155](https://github.com/defi-wonderland/smock/issues/155)) ([b71cfd1](https://github.com/defi-wonderland/smock/commit/b71cfd118a2a9579517769c0c31abede7d83ca71))


### Bug Fixes

* bug with usage of padNumHexSlotValue ([#161](https://github.com/defi-wonderland/smock/issues/161)) ([9cffea6](https://github.com/defi-wonderland/smock/commit/9cffea640c4bd5ddc09a638505f6bb0a0cebdbad))
* delegated calls support ([#132](https://github.com/defi-wonderland/smock/issues/132)) ([812c335](https://github.com/defi-wonderland/smock/commit/812c3354d77603d8a6db172f5297c8e49625a98b))
* duplicated type ([#138](https://github.com/defi-wonderland/smock/issues/138)) ([823b0ea](https://github.com/defi-wonderland/smock/commit/823b0ea7ed422636e4e763576b6975a422728522))

## [2.3.0](https://github.com/defi-wonderland/smock/compare/v2.1.0...v2.3.0) (2022-09-08)


Expand Down
28 changes: 11 additions & 17 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,15 @@

[![image](https://badgen.net/badge/icon/discord?icon=discord&label)](https://discord.com/invite/22RQcJjau9)

```{=html}
<div align="center">
<a href="https://github.com/defi-wonderland/smock">
<img src="https://user-images.githubusercontent.com/14298799/128897259-1d2c43b5-9156-425e-82e0-ab13f259e57c.gif" width="400px">
</a>
</div>
<br />
<br />

```
**Smock** is the **S**olidity **mock**ing library. It\'s a plugin for
[hardhat](https://hardhat.org) that can be used to create mock Solidity
contracts entirely in JavaScript (or TypeScript!). With Smock, it\'s
Expand All @@ -26,8 +27,7 @@ testing frameworks like [Truffle](https://www.trufflesuite.com/).
If you wanna chat about the future of Solidity Mocking, join our
[Discord](https://discord.com/invite/22RQcJjau9)!

Features
========
# Features

- Get rid of your folder of \"mock\" contracts and **just use
JavaScript**.
Expand All @@ -39,31 +39,27 @@ Features
- Make **assertions** about calls, call arguments, and call counts.
- We\'ve got extensive documentation and a complete test suite.

Documentation
=============
# Documentation

Detailed documentation can be found
[here](https://smock.readthedocs.io).

Quick Start
===========
# Quick Start

Installation
------------
## Installation

You can install Smock via npm or yarn:

``` {.sourceCode .console}
``` console
npm install @defi-wonderland/smock
```

Basic Usage
-----------
## Basic Usage

Smock is dead simple to use. Here\'s a basic example of how you might
use it to streamline your tests.

``` {.sourceCode .typescript}
``` typescript
...
import { FakeContract, smock } from '@defi-wonderland/smock';

Expand All @@ -86,16 +82,14 @@ describe('MyContract', () => {
});
```

License
=======
# License

Smock is released under the MIT license. Feel free to use, modify,
and/or redistribute this software as you see fit. See the
[LICENSE](https://github.com/defi-wonderland/smock/blob/main/LICENSE)
file for more information.

Contributors
============
# Contributors

Maintained with love by [Optimism PBC](https://optimism.io) and [DeFi
Wonderland](https://defi.sucks). Made possible by viewers like you.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@defi-wonderland/smock",
"version": "2.3.0",
"version": "2.3.1",
"description": "The Solidity mocking library",
"keywords": [
"ethereum",
Expand Down
18 changes: 9 additions & 9 deletions src/utils/storage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -252,7 +252,7 @@ function encodeVariable(
return [
{
key: slotKey,
val: padNumHexSlotValue(variable, storageObj.offset),
val: padBytesHexSlotValue(variable, storageObj.offset),
},
];
} else if (variableType.label === 'bool') {
Expand Down Expand Up @@ -381,19 +381,19 @@ function encodeVariable(
// Mapping keys are encoded depending on the key type.
let key: string;
if (variableType.key.startsWith('t_uint')) {
key = BigNumber.from(varName).toHexString();
key = padNumHexSlotValue(BigNumber.from(varName).toHexString(), 0);
} else if (variableType.key.startsWith('t_bytes')) {
key = '0x' + remove0x(varName).padEnd(64, '0');
key = padBytesHexSlotValue('0x' + remove0x(varName).padEnd(64, '0'), 0);
} else {
// Seems to work for everything else.
key = varName;
key = padBytesHexSlotValue(varName, 0);
}

// Figure out the base slot key that the mapped values need to work off of.
// If baseSlotKey is defined here, then we're inside of a nested mapping and we should work
// off of that previous baseSlotKey. Otherwise the base slot will be the slot of this map.
const prevBaseSlotKey = baseSlotKey || padNumHexSlotValue(storageObj.slot, 0);
const nextBaseSlotKey = ethers.utils.keccak256(padNumHexSlotValue(key, 0) + remove0x(prevBaseSlotKey));
const nextBaseSlotKey = ethers.utils.keccak256(key + remove0x(prevBaseSlotKey));

// Encode the value. We need to use a dummy storageObj here because the function expects it.
// Of course, we're not mapping to a specific variable. We map to a variable /type/. So we
Expand Down Expand Up @@ -656,20 +656,20 @@ async function getMappingTypeStorageSlots(
// In this part we calculate the `h(k)` where k is the mapping key the user provided and h is a function that is applied to the key depending on its type
let mappKey: string;
if (storageObjectType.key.startsWith('t_uint')) {
mappKey = BigNumber.from(mappingKey[0]).toHexString();
mappKey = padNumHexSlotValue(BigNumber.from(mappingKey[0]).toHexString(), 0);
} else if (storageObjectType.key.startsWith('t_bytes')) {
mappKey = '0x' + remove0x(mappingKey[0] as string).padEnd(64, '0');
mappKey = padBytesHexSlotValue('0x' + remove0x(mappingKey[0] as string).padEnd(64, '0'), 0);
} else {
// Seems to work for everything else.
mappKey = mappingKey[0] as string;
mappKey = padBytesHexSlotValue(mappingKey[0] as string, 0);
}

// Figure out the base slot key that the mapped values need to work off of.
// If baseSlotKey is defined here, then we're inside of a nested mapping and we should work
// off of that previous baseSlotKey. Otherwise the base slot will be the key we already have.
const prevBaseSlotKey = baseSlotKey || key;
// Since we have `h(k) = mappKey` and `p = key` now we can calculate the slot key
let nextSlotKey = ethers.utils.keccak256(padNumHexSlotValue(mappKey, 0) + remove0x(prevBaseSlotKey));
let nextSlotKey = ethers.utils.keccak256(mappKey + remove0x(prevBaseSlotKey));

let slotKeysTypes: StorageSlotKeyTypePair[] = [];

Expand Down
6 changes: 3 additions & 3 deletions test/contracts/mock/StorageGetter.sol
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ contract StorageGetter {
PackedStruct internal _packedStruct;
mapping(uint256 => uint256) _uint256Map;
mapping(uint256 => mapping(uint256 => uint256)) _uint256NestedMap;
mapping(bytes5 => bool) _bytes5ToBoolMap;
mapping(bytes32 => bool) _bytes32ToBoolMap;
mapping(address => bool) _addressToBoolMap;
mapping(address => address) _addressToAddressMap;
uint256[] internal _uint256Array;
Expand Down Expand Up @@ -119,8 +119,8 @@ contract StorageGetter {
return _uint256NestedMap[_keyA][_keyB];
}

function getBytes5ToBoolMapValue(bytes5 _key) public view returns (bool _out) {
return _bytes5ToBoolMap[_key];
function getBytes32ToBoolMapValue(bytes32 _key) public view returns (bool _out) {
return _bytes32ToBoolMap[_key];
}

function getAddressToBoolMapValue(address _key) public view returns (bool _out) {
Expand Down
15 changes: 8 additions & 7 deletions test/unit/mock/editable-storage-logic.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { ADDRESS_EXAMPLE, BYTES32_EXAMPLE, BYTES_EXAMPLE } from '@test-utils';
import { StorageGetter, StorageGetter__factory } from '@typechained';
import { expect } from 'chai';
import { BigNumber, utils } from 'ethers';
import { defaultAbiCoder, keccak256 } from 'ethers/lib/utils';

describe('Mock: Editable storage logic', () => {
let storageGetterFactory: MockContractFactory<StorageGetter__factory>;
Expand Down Expand Up @@ -125,12 +126,12 @@ describe('Mock: Editable storage logic', () => {
expect(await mock.getConstructorUint256()).to.equal(1234);
});

it('should be able to set values in a bytes5 => bool mapping', async () => {
const mapKey = '0x0000005678';
it('should be able to set values in a bytes32 => bool mapping', async () => {
const mapKey = keccak256(defaultAbiCoder.encode(['bytes32'], [BYTES32_EXAMPLE]));
const mapValue = true;
await mock.setVariable('_bytes5ToBoolMap', { [mapKey]: mapValue });
await mock.setVariable('_bytes32ToBoolMap', { [mapKey]: mapValue });

expect(await mock.getBytes5ToBoolMapValue(mapKey)).to.equal(mapValue);
expect(await mock.getBytes32ToBoolMapValue(mapKey)).to.equal(mapValue);
});

it('should be able to set values in a address => bool mapping', async () => {
Expand Down Expand Up @@ -260,7 +261,7 @@ describe('Mock: Editable storage logic', () => {
const mapKeyB = 5678;
const mapValue = 4321;
const mapValueB = 8765;
const mapKeybytes5ToBool = '0x0000005678';
const mapKeybytes32ToBool = BYTES32_EXAMPLE;
const mapValueAddress = '0x063bE0Af9711a170BE4b07028b320C90705fec7C';
await mock.setVariables({
_address: ADDRESS_EXAMPLE,
Expand All @@ -276,7 +277,7 @@ describe('Mock: Editable storage logic', () => {
[mapKeyB]: mapValueB,
},
},
_bytes5ToBoolMap: { [mapKeybytes5ToBool]: true },
_bytes32ToBoolMap: { [mapKeybytes32ToBool]: true },
_addressToBoolMap: { [ADDRESS_EXAMPLE]: false },
_addressToAddressMap: { [ADDRESS_EXAMPLE]: mapValueAddress },
});
Expand All @@ -290,7 +291,7 @@ describe('Mock: Editable storage logic', () => {
expect(convertStructToPojo(await mock.getSimpleStruct())).to.deep.equal(struct);
expect(await mock.getUint256MapValue(mapKey)).to.equal(mapValue);
expect(await mock.getNestedUint256MapValue(mapKey, mapKeyB)).to.equal(mapValueB);
expect(await mock.getBytes5ToBoolMapValue(mapKeybytes5ToBool)).to.equal(true);
expect(await mock.getBytes32ToBoolMapValue(mapKeybytes32ToBool)).to.equal(true);
expect(await mock.getAddressToBoolMapValue(ADDRESS_EXAMPLE)).to.equal(false);
expect(await mock.getAddressToAddressMapValue(ADDRESS_EXAMPLE)).to.equal(mapValueAddress);
});
Expand Down
10 changes: 5 additions & 5 deletions test/unit/mock/readable-storage-logic.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -121,13 +121,13 @@ describe('Mock: Readable storage logic', () => {
expect(getValue).to.equal(await mock.getUint256MapValue(mapKey));
});

it('should be able to get values in a bytes5 => bool mapping', async () => {
const mapKey = '0x0000005678';
it('should be able to get values in a bytes32 => bool mapping', async () => {
const mapKey = BYTES32_EXAMPLE;
const mapValue = true;
await mock.setVariable('_bytes5ToBoolMap', { [mapKey]: mapValue });
await mock.setVariable('_bytes32ToBoolMap', { [mapKey]: mapValue });

const getValue = await mock.getVariable('_bytes5ToBoolMap', [mapKey]);
expect(getValue).to.equal(await mock.getBytes5ToBoolMapValue(mapKey));
const getValue = await mock.getVariable('_bytes32ToBoolMap', [mapKey]);
expect(getValue).to.equal(await mock.getBytes32ToBoolMapValue(mapKey));
});

it('should be able to get a nested uint256 mapping value', async () => {
Expand Down

0 comments on commit 201ba01

Please sign in to comment.