🚀 Socket Launch Week Day 5:Introducing Repository Access Permissions and Custom Roles.Learn more
Sign In

@ensofinance/weiroll

Package Overview
Dependencies
Maintainers
9
Versions
8
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@ensofinance/weiroll - npm Package Compare versions

Comparing version
1.1.0
to
1.2.0
contracts/test/Fallback.sol

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

+4
-4
{
"name": "@ensofinance/weiroll",
"version": "1.1.0",
"version": "1.2.0",
"devDependencies": {
"@ensofinance/weiroll.js": "^0.3.0",
"@nomiclabs/hardhat-ethers": "^2.0.2",
"@nomiclabs/hardhat-waffle": "^2.0.1",
"@openzeppelin/contracts": "^4.1.0",
"@weiroll/weiroll.js": "^0.3.0",
"chai": "^4.3.4",
"ethereum-waffle": "^3.3.0",
"ethereum-waffle": "^4.0.4",
"ethers": "^5.3.1",
"hardhat": "^2.8.4",
"prettier": "^2.3.1",
"prettier-plugin-solidity": "*",
"prettier-plugin-solidity": "1.0.0-beta.24",
"solhint-plugin-prettier": "^0.0.5",

@@ -16,0 +16,0 @@ "ts-node": "^10.6.0",

@@ -39,5 +39,5 @@ # Weiroll

0 1 2 3 4 5 6 7
┌───┬───┬───────────────┬────────┐
│tup│ext│ reserved │calltype│
└───┴───┴───────────────┴────────┘
┌───┬───┬───┬───────────┬────────┐
│tup│ext│dat│ reserved │calltype│
└───┴───┴───┴───────────┴────────┘
```

@@ -49,4 +49,6 @@

Bits 2-5 are reserved for future use.
If `dat` is set, the msg.data will be assigned from the state slot directly, without any attempt at encoding.
Bits 3-5 are reserved for future use.
The 2-bit `calltype` is treated as a `uint16` that specifies the type of call. The value that selects the corresponding call type is described in the table below:

@@ -80,5 +82,5 @@

The `var` flag indicates if the indexed value should be treated as fixed- or variable-length. If `var == 0b`, the argument is fixed-length, and `idx`, is treated as the index into the state array at which the value is located. The state entry at that index must be exactly 32 bytes long.
The `var` flag indicates if the indexed value should be treated as fixed- or variable-length. If `var == 0b`, the argument is fixed-length, and `idx`, is treated as the index into the state array at which the value is located. The state entry at that index must be exactly 32 bytes long (except if overriding msg.data directly via `dat` flag).
If `var == 1b`, the indexed value is treated as variable-length, and `idx` is treated as the index into the state array at which the value is located. The value must be a multiple of 32 bytes long.
If `var == 1b`, the indexed value is treated as variable-length, and `idx` is treated as the index into the state array at which the value is located. The value must be a multiple of 32 bytes long (except if overriding msg.data directly via `dat` flag).

@@ -85,0 +87,0 @@ The vm handles the "head" part of ABI-encoding and decoding for variable-length values, so the state elements for these should be the "tail" part of the encoding - for example, a string encodes as a 32 byte length field followed by the string data, padded to a 32-byte boundary, and an array of `uint`s is a 32 byte count followed by the concatenation of all the uints.

const { expect } = require("chai");
const { ethers } = require("hardhat");
const weiroll = require("@weiroll/weiroll.js");
const weiroll = require("@ensofinance/weiroll.js");

@@ -25,13 +25,30 @@ async function deployLibrary(name) {

async function executeBuildInputs(commands, state, abiout, msg){
async function executeBuildInputs(commands, state, abiout, msg) {
for (let c of commands) {
selector = ethers.utils.hexDataSlice(c, 0, 4);
indices = ethers.utils.hexConcat([ethers.utils.hexDataSlice(c, 5, 5+6), "0xffffffffffffffffffffffffffffffffffffffffffffffffffff"]);
target = ethers.utils.hexDataSlice(c, 5+6);
const txBaseGasNoArgs = await cbh.estimateGas.basecall();
const txBaseGas = await cbh.estimateGas.testBuildInputsBaseGas(state, selector, indices);
const txGas = await cbh.estimateGas.testBuildInputs(state, selector, indices);
console.log(`buildInputs gas cost: ${txGas.sub(txBaseGas).toString()} - argument passing cost: ${txBaseGas.sub(txBaseGasNoArgs).toNumber()} - total: ${txGas.toNumber()}`)
const result = await cbh.testBuildInputs(state, selector, indices);
expect(result).to.equal(selector + abiout.slice(2));
selector = ethers.utils.hexDataSlice(c, 0, 4);
indices = ethers.utils.hexConcat([
ethers.utils.hexDataSlice(c, 5, 5 + 6),
"0xffffffffffffffffffffffffffffffffffffffffffffffffffff",
]);
target = ethers.utils.hexDataSlice(c, 5 + 6);
const txBaseGasNoArgs = await cbh.estimateGas.basecall();
const txBaseGas = await cbh.estimateGas.testBuildInputsBaseGas(
state,
selector,
indices
);
const txGas = await cbh.estimateGas.testBuildInputs(
state,
selector,
indices
);
console.log(
`buildInputs gas cost: ${txGas
.sub(txBaseGas)
.toString()} - argument passing cost: ${txBaseGas
.sub(txBaseGasNoArgs)
.toNumber()} - total: ${txGas.toNumber()}`
);
const result = await cbh.testBuildInputs(state, selector, indices);
expect(result).to.equal(selector + abiout.slice(2));
}

@@ -49,3 +66,3 @@ }

const {commands, state} = planner.plan();
const { commands, state } = planner.plan();

@@ -64,6 +81,5 @@ await executeBuildInputs(commands, state, abiout, "Math.add");

const {commands, state} = planner.plan();
const { commands, state } = planner.plan();
await executeBuildInputs(commands, state, abiout, "Strings.strcat");
});

@@ -75,5 +91,11 @@

let args = [
ethers.BigNumber.from("0xAAA0000000000000000000000000000000000000000000000000000000000002"),
ethers.BigNumber.from("0x1111111111111111111111111111111111111111111111111111111111111111"),
ethers.BigNumber.from("0x2222222222222222222222222222222222222222222222222222222222222222")
ethers.BigNumber.from(
"0xAAA0000000000000000000000000000000000000000000000000000000000002"
),
ethers.BigNumber.from(
"0x1111111111111111111111111111111111111111111111111111111111111111"
),
ethers.BigNumber.from(
"0x2222222222222222222222222222222222222222222222222222222222222222"
),
];

@@ -85,23 +107,26 @@

const {commands, state} = planner.plan();
const { commands, state } = planner.plan();
await executeBuildInputs(commands, state, abiout, "Math.sum");
});
it("Should select and overwrite first 32 byte slot in state for output (static test)", async () => {
let state = [
"0x000000000000000000000000000000000000000000000000000000000000000a",
"0x1111111111111111111111111111111111111111111111111111111111111111",
"0x2222222222222222222222222222222222222222222222222222222222222222"
"0x2222222222222222222222222222222222222222222222222222222222222222",
];
let index = "0x00";
let output = "0x0000000000000000000000000000000000000000000000000000000000000000";
let output =
"0x0000000000000000000000000000000000000000000000000000000000000000";
const txBaseGas = await cbh.estimateGas.testWriteOutputsBaseGas(state, index, output);
const txBaseGas = await cbh.estimateGas.testWriteOutputsBaseGas(
state,
index,
output
);
const txGas = await cbh.estimateGas.testWriteOutputs(state, index, output);
console.log("writeOutputs gas cost: ", txGas.sub(txBaseGas).toString())
console.log("writeOutputs gas cost: ", txGas.sub(txBaseGas).toString());
const tx = await cbh.testWriteOutputs(state, index, output);

@@ -115,16 +140,19 @@

it("Should select and overwrite second dynamic amount bytes in second state slot given a uint[] output (dynamic test)", async () => {
let state = [
"0x000000000000000000000000000000000000000000000000000000000000000a",
"0x1111111111111111111111111111111111111111111111111111111111111111",
"0x2222222222222222222222222222222222222222222222222222222222222222"
"0x2222222222222222222222222222222222222222222222222222222222222222",
];
let index = "0x81";
let output = abi.encode(["uint[]"], [[1, 2, 3]]);
const txBaseGas = await cbh.estimateGas.testWriteOutputsBaseGas(state, index, output);
const txBaseGas = await cbh.estimateGas.testWriteOutputsBaseGas(
state,
index,
output
);
const txGas = await cbh.estimateGas.testWriteOutputs(state, index, output);
console.log("writeOutputs gas cost: ", txGas.sub(txBaseGas).toString())
console.log("writeOutputs gas cost: ", txGas.sub(txBaseGas).toString());
const tx = await cbh.testWriteOutputs(state, index, output);

@@ -137,11 +165,9 @@

it("Should overwrite entire state with *abi decoded* output value (rawcall)", async () => {
let state = [
"0x000000000000000000000000000000000000000000000000000000000000000a",
"0x1111111111111111111111111111111111111111111111111111111111111111",
"0x2222222222222222222222222222222222222222222222222222222222222222"
"0x2222222222222222222222222222222222222222222222222222222222222222",
];
let index = "0xfe";

@@ -153,5 +179,9 @@

const txBaseGas = await cbh.estimateGas.testWriteOutputsBaseGas(state, index, output);
const txBaseGas = await cbh.estimateGas.testWriteOutputsBaseGas(
state,
index,
output
);
const txGas = await cbh.estimateGas.testWriteOutputs(state, index, output);
console.log("writeOutputs gas cost: ", txGas.sub(txBaseGas).toString())
console.log("writeOutputs gas cost: ", txGas.sub(txBaseGas).toString());
const tx = await cbh.testWriteOutputs(state, index, output);

@@ -161,3 +191,2 @@

});
});

@@ -5,7 +5,8 @@ const { expect } = require("chai");

describe("Tuple", function () {
let vm, multiReturn, tupler;
before(async () => {
multiReturn = await (await ethers.getContractFactory("MultiReturn")).deploy();
multiReturn = await (
await ethers.getContractFactory("MultiReturn")
).deploy();
tupler = await (await ethers.getContractFactory("LibTupler")).deploy();

@@ -30,7 +31,6 @@

it("Should perform a tuple return that's sliced before being fed to another function (first var)", async () => {
const commands = [
[multiReturn, "intTuple", "0x80ffffffffffff", "0x00"],
[tupler, "extractElement","0x008001ffffffff", "0x00"],
[multiReturn, "tupleConsumer", "0x0000ffffffffff", "0xff"]
[multiReturn, "intTuple", "0x80ffffffffffff", "0x00"],
[tupler, "extractElement", "0x008001ffffffff", "0x00"],
[multiReturn, "tupleConsumer", "0x0000ffffffffff", "0xff"],
];

@@ -43,3 +43,2 @@

const tx = await execute(commands, state);

@@ -56,10 +55,8 @@

it("Should perform a tuple return that's sliced before being fed to another function (second var)", async () => {
const commands = [
[multiReturn, "intTuple", "0x80ffffffffffff", "0x00"],
[tupler, "extractElement","0x008001ffffffff", "0x00"],
[multiReturn, "tupleConsumer", "0x0000ffffffffff", "0xff"]
[multiReturn, "intTuple", "0x80ffffffffffff", "0x00"],
[tupler, "extractElement", "0x008001ffffffff", "0x00"],
[multiReturn, "tupleConsumer", "0x0000ffffffffff", "0xff"],
];
const state = [

@@ -70,3 +67,2 @@ "0x0000000000000000000000000000000000000000000000000000000000000000",

const tx = await execute(commands, state);

@@ -76,3 +72,3 @@

.to.emit(multiReturn.attach(vm.address), "Calculated")
.withArgs(0xdeed);
.withArgs(0xdeed);

@@ -79,0 +75,0 @@ const receipt = await tx.wait();

const { expect } = require("chai");
const { ethers } = require("hardhat");
const weiroll = require("@weiroll/weiroll.js");
const weiroll = require("@ensofinance/weiroll.js");
async function deployLibrary(name) {
const factory = await ethers.getContractFactory(name);
const contract = await factory.deploy();
return weiroll.Contract.createLibrary(contract);
}
const deploy = async (name) => (await ethers.getContractFactory(name)).deploy();
async function deployContract(name) {
const factory = await ethers.getContractFactory(name);
const contract = await factory.deploy();
return weiroll.Contract.createContract(contract);
}
const deployLibrary = async (name) =>
weiroll.Contract.createLibrary(await deploy(name));
const deployContract = async (name) =>
weiroll.Contract.createContract(await deploy(name));
describe("VM", function () {
const testString = "Hello, world!";
let events, vm, math, strings, stateTest, sender, revert, vmLibrary, token;
let events,
vm,
math,
strings,
stateTest,
sender,
revert,
fallback,
token,
payable;
let supply = ethers.BigNumber.from("100000000000000000000");
let eventsContract;
let eventsContract, fallbackContract;

@@ -29,10 +34,13 @@ before(async () => {

revert = await deployLibrary("Revert");
receiver = await deployContract("Receiver");
payable = await deployContract("Payable");
stateTest = await deployContract("StateTest");
fallbackContract = await (
await ethers.getContractFactory("Fallback")
).deploy();
fallback = weiroll.Contract.createContract(fallbackContract);
eventsContract = await (await ethers.getContractFactory("Events")).deploy();
events = weiroll.Contract.createLibrary(eventsContract);
const StateTest = await ethers.getContractFactory("StateTest");
stateTest = await StateTest.deploy();
const VM = await ethers.getContractFactory("TestableVM");

@@ -46,6 +54,6 @@ vm = await VM.deploy();

function execute(commands, state) {
function execute(commands, state, overrides) {
let encodedCommands = commands.map(([target, func, inargs, outargs]) =>
ethers.utils.concat([
target.interface.getSighash(func),
func ? target.interface.getSighash(func) : "0x12345678",
inargs,

@@ -56,3 +64,3 @@ outargs,

);
return vm.execute(encodedCommands, state);
return vm.execute(encodedCommands, state, { ...overrides });
}

@@ -77,2 +85,51 @@

it("Should call fallback", async () => {
const commands = [[fallback, "", "0x2180ffffffffff", "0xff"]];
const state = ["0x"];
const tx = await execute(commands, state);
await expect(tx).to.not.emit(fallbackContract, "LogBytes");
const receipt = await tx.wait();
console.log(`fallback: ${receipt.gasUsed.toNumber()} gas`);
});
it("Should call fallback with overriden msg.data and msg.value", async () => {
const msgValue = ethers.constants.WeiPerEther;
const msgData = ethers.utils.hexlify(ethers.utils.toUtf8Bytes(testString));
const commands = [[fallback, "", "0x230081ffffffff", "0xff"]];
const state = [
ethers.utils.hexZeroPad(msgValue.toHexString(), "32"),
msgData,
];
const tx = await execute(commands, state, { value: msgValue });
await expect(tx).to.emit(fallbackContract, "LogUint").withArgs(msgValue);
await expect(tx).to.emit(fallbackContract, "LogBytes").withArgs(msgData);
const receipt = await tx.wait();
console.log(
`fallback (override msg.value & msg.data): ${receipt.gasUsed.toNumber()} gas`
);
});
it("Should call function named fallback with msg.value", async () => {
const planner = new weiroll.Planner();
const msgValue = ethers.constants.WeiPerEther;
const data = ethers.utils.hexlify(ethers.utils.toUtf8Bytes(testString));
planner.add(fallback.fallback(data).withValue(msgValue));
const { commands, state } = planner.plan();
const tx = await vm.execute(commands, state, { value: msgValue });
await expect(tx).to.emit(fallbackContract, "LogUint").withArgs(msgValue);
await expect(tx).to.emit(fallbackContract, "LogBytes").withArgs(data);
const receipt = await tx.wait();
console.log(`fallback (named function): ${receipt.gasUsed.toNumber()} gas`);
});
it("Should execute a simple addition program", async () => {

@@ -89,3 +146,3 @@ const planner = new weiroll.Planner();

const { commands, state } = planner.plan();
const tx = await vm.execute(commands, state);

@@ -100,18 +157,2 @@ await expect(tx)

it("Should execute a simple receiver program", async () => {
const planner = new weiroll.Planner();
const value = 100;
const balanceBefore = await ethers.provider.getBalance(receiver.address)
expect(parseInt(balanceBefore)).to.be.equal(0)
const ret = planner.add(receiver.receive(value).withValue(value));
const { commands, state } = planner.plan();
const tx = await vm.execute(commands, state, {value: value});
const receipt = await tx.wait();
console.log(`Array sum: ${receipt.gasUsed.toNumber()} gas`);
const balanceAfter = await ethers.provider.getBalance(receiver.address)
expect(parseInt(balanceAfter)).to.be.equal(value)
});
it("Should execute a string length program", async () => {

@@ -162,15 +203,21 @@ const planner = new weiroll.Planner();

it("Should sum an array of uints using extended flag", async () => {
it("Should execute payable function", async () => {
const amount = ethers.constants.WeiPerEther.mul(123);
const planner = new weiroll.Planner();
const result = planner.add(math.sumExtended(1, 2, 3, 4, 5, 6, 7));
planner.add(events.logUint(result));
planner.add(payable.pay().withValue(amount));
const balance = planner.add(payable.balance());
planner.add(
weiroll.Contract.createContract(eventsContract).logUint(balance)
);
const { commands, state } = planner.plan();
const tx = await vm.execute(commands, state);
await expect(tx)
.to.emit(eventsContract.attach(vm.address), "LogUint")
.withArgs(28);
const tx = await vm.execute(commands, state, { value: amount });
await expect(tx).to.emit(eventsContract, "LogUint").withArgs(amount);
expect(await ethers.provider.getBalance(payable.address)).to.be.equal(
amount
);
const receipt = await tx.wait();
console.log(`String concatenation: ${receipt.gasUsed.toNumber()} gas`);
console.log(`Payable: ${receipt.gasUsed.toNumber()} gas`);
});

@@ -242,5 +289,5 @@

await expect(vm.execute(commands, state)).to.be.revertedWith(
"Hello World!"
"ExecutionFailed"
);
});
});

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet