Skip to content

Commit

Permalink
Merge branch 'dev' into dev
Browse files Browse the repository at this point in the history
  • Loading branch information
hellwolf authored Dec 17, 2024
2 parents 857991e + d59ec69 commit afaaf81
Show file tree
Hide file tree
Showing 10 changed files with 201 additions and 19 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/handler.publish-pr-packages.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ jobs:
- name: Download artifact
continue-on-error: true
id: download_artifact
uses: dawidd6/action-download-artifact@v4
uses: dawidd6/action-download-artifact@v6
with:
workflow: ${{ github.event.workflow_run.workflow_id }}
workflow_conclusion: success
Expand Down
1 change: 1 addition & 0 deletions flake.nix
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@
# test utilities
lcov
actionlint
git
];

# solidity dev inputs
Expand Down
6 changes: 6 additions & 0 deletions packages/sdk-core/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,12 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
### Changed
### Fixed

## [0.9.0] - 2024-12-13

### Added
- Handle new Operation types with BatchCall
- Forward ETH value with BatchCall and Operation

## [0.8.0] - 2024-08-01

### Breaking
Expand Down
4 changes: 2 additions & 2 deletions packages/sdk-core/package.json
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
{
"name": "@superfluid-finance/sdk-core",
"description": "SDK Core for building with Superfluid Protocol",
"version": "0.8.0",
"version": "0.9.0",
"bugs": "https://github.com/superfluid-finance/protocol-monorepo/issues",
"dependencies": {
"@superfluid-finance/ethereum-contracts": "1.12.0",
"@superfluid-finance/metadata": "^1.5.2",
"browserify": "17.0.0",
"graphql-request": "6.1.0",
"lodash": "4.17.21",
"tsify": "5.0.4"
Expand All @@ -16,6 +15,7 @@
"@graphql-codegen/near-operation-file-preset": "^3.0.0",
"@graphql-typed-document-node/core": "^3.2.0",
"ajv": "^8.17.1",
"browserify": "^17.0.1",
"ethers": "^5.7.2",
"get-graphql-schema": "^2.1.2",
"mocha": "^10.7.3"
Expand Down
28 changes: 23 additions & 5 deletions packages/sdk-core/src/BatchCall.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { JsonFragment } from "@ethersproject/abi";
import { ethers } from "ethers";
import { BigNumber, ethers } from "ethers";

import Host from "./Host";
import Operation, { BatchOperationType } from "./Operation";
Expand All @@ -15,6 +15,7 @@ export interface OperationStruct {
readonly operationType: number;
readonly target: string;
readonly data: string;
readonly value?: ethers.BigNumber;
}

export const batchOperationTypeStringToTypeMap = new Map<
Expand All @@ -30,6 +31,8 @@ export const batchOperationTypeStringToTypeMap = new Map<
["SUPERTOKEN_DOWNGRADE", 102],
["SUPERFLUID_CALL_AGREEMENT", 201],
["CALL_APP_ACTION", 202],
["SIMPLE_FORWARD_CALL", 301],
["ERC2771_FORWARD_CALL", 302],
]);

/**
Expand Down Expand Up @@ -89,10 +92,25 @@ export default class BatchCall {
const operationStructArray = await Promise.all(
this.getOperationStructArrayPromises
);
const tx =
this.host.contract.populateTransaction.batchCall(
operationStructArray
);

const values = operationStructArray
.filter((x) => x.value?.gt(BigNumber.from(0)))
.map((x) => x.value);

if (values.length > 1) {
throw new SFError({
type: "BATCH_CALL_ERROR",
message:
"There are multiple values in the batch call. The value can only be forwarded to one receiving operation.",
});
}

const tx = this.host.contract.populateTransaction.batchCall(
operationStructArray,
{
value: values?.length > 0 ? values[0] : undefined,
}
);
return new Operation(tx, "UNSUPPORTED");
}

Expand Down
21 changes: 19 additions & 2 deletions packages/sdk-core/src/Operation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,9 @@ export type BatchOperationType =
| "SUPERTOKEN_UPGRADE" // 101
| "SUPERTOKEN_DOWNGRADE" // 102
| "SUPERFLUID_CALL_AGREEMENT" // 201
| "CALL_APP_ACTION"; // 202
| "CALL_APP_ACTION" // 202
| "SIMPLE_FORWARD_CALL" // 301
| "ERC2771_FORWARD_CALL"; // 302

/**
* Operation Helper Class
Expand Down Expand Up @@ -164,6 +166,7 @@ export default class Operation {
operationType: batchOperationType,
target: functionArgs["agreementClass"],
data,
value: populatedTransaction.value,
};
}

Expand All @@ -178,14 +181,28 @@ export default class Operation {
operationType: batchOperationType,
target: functionArgs["app"],
data: functionArgs["callData"],
value: populatedTransaction.value,
};
}

// Handles remaining ERC20/ERC777/SuperToken Operations
if (
this.type === "SIMPLE_FORWARD_CALL" ||
this.type === "ERC2771_FORWARD_CALL"
) {
return {
operationType: batchOperationType,
target: populatedTransaction.to,
data: populatedTransaction.data,
value: populatedTransaction.value,
};
}

// Handles remaining ERC20/ERC777/SuperToken Operations (including SIMPLE_FORWARD_CALL and ERC2771_FORWARD_CALL)
return {
operationType: batchOperationType,
target: populatedTransaction.to,
data: removeSigHashFromCallData(populatedTransaction.data),
value: populatedTransaction.value,
};
};
}
29 changes: 28 additions & 1 deletion packages/sdk-core/test/2_operation.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { SuperAppTester } from "../typechain-types";
import { SuperAppTester__factory } from "../typechain-types";
const cfaInterface = IConstantFlowAgreementV1__factory.createInterface();
import { TestEnvironment, makeSuite } from "./TestEnvironment";
import { ethers } from "ethers";
import { BigNumber, ethers } from "ethers";
import multiplyGasLimit from "../src/multiplyGasLimit";

/**
Expand Down Expand Up @@ -174,6 +174,33 @@ makeSuite("Operation Tests", (testEnv: TestEnvironment) => {
expect(txn.gasLimit).to.equal("500000");
});

it("Should move ETH value passed from the Overrides", async () => {
const value = BigNumber.from(Number(0.1e18).toString());

const beforeBalanceAlice = await testEnv.alice.getBalance();
const beforeBalanceBob = await testEnv.bob.getBalance();

expect(beforeBalanceAlice.gt(value)).to.be.true;

const operation = testEnv.sdkFramework.operation(
testEnv.alice.populateTransaction({
to: testEnv.bob.address,
value
}) as Promise<ethers.PopulatedTransaction>,
"SIMPLE_FORWARD_CALL"
);

const txn = await operation.exec(testEnv.alice, 2);
const txReceipt = await txn.wait();
expect(txReceipt.status).to.equal(1);

const afterBalanceAlice = await testEnv.alice.getBalance();
const afterBalanceBob = await testEnv.bob.getBalance();

expect(afterBalanceBob.sub(beforeBalanceBob)).to.equal(value);
expect(beforeBalanceAlice.sub(afterBalanceAlice).gte(value)).to.be.true;
});

it("Should throw an error when trying to execute a transaction with faulty callData", async () => {
const callData = cfaInterface.encodeFunctionData("createFlow", [
testEnv.wrapperSuperToken.address,
Expand Down
115 changes: 114 additions & 1 deletion packages/sdk-core/test/3_batch_call.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@ import { expect } from "chai";
import {
AUTHORIZE_FULL_CONTROL,
Operation,
TestToken,
TestToken__factory,
getPerSecondFlowRateByMonth,
toBN,
} from "../src";
import { ethers } from "ethers";
import { BigNumber, Contract, ethers } from "ethers";
import { createCallAppActionOperation } from "./2_operation.test";
import { TestEnvironment, makeSuite } from "./TestEnvironment";

Expand Down Expand Up @@ -408,4 +410,115 @@ makeSuite("Batch Call Tests", (testEnv: TestEnvironment) => {
"0"
);
});


it("Should be able to execute SimpleForwarder batch call", async () => {
const contract = (new Contract(
testEnv.wrapperSuperToken.underlyingToken.address,
TestToken__factory.abi
) as TestToken).connect(testEnv.alice);

const beforeBalance = await contract.balanceOf(testEnv.alice.address);

const txn1 = contract
.populateTransaction.mint(
testEnv.alice.address,
"100"
);
const txn2 = contract
.populateTransaction.mint(
testEnv.alice.address,
"200"
);

const operation1 = testEnv.sdkFramework.operation(
txn1,
"SIMPLE_FORWARD_CALL"
);
const operation2 = testEnv.sdkFramework.operation(
txn2,
"SIMPLE_FORWARD_CALL"
);

const batchCall = testEnv.sdkFramework.batchCall(
[
operation1,
operation2
]
);

const txResponse = await batchCall.exec(testEnv.alice);
const txReceipt = await txResponse.wait();
expect(txReceipt.status).to.equal(1);

const afterBalance = await contract.balanceOf(testEnv.alice.address);

expect(beforeBalance.lt(afterBalance)).to.be.true;
expect(afterBalance.sub(BigNumber.from(300)).eq(beforeBalance)).to.be.true;
});

it("Should be able to move ETH value", async () => {
const value = BigNumber.from(Number(0.1e18).toString());

const beforeBalanceAlice = await testEnv.alice.getBalance();
const beforeBalanceBob = await testEnv.bob.getBalance();

expect(beforeBalanceAlice.gt(value)).to.be.true;

const operation = testEnv.sdkFramework.operation(
testEnv.alice.populateTransaction({
to: testEnv.bob.address,
value,
data: "0x"
}) as Promise<ethers.PopulatedTransaction>,
"SIMPLE_FORWARD_CALL"
);

const batchCall = testEnv.sdkFramework.batchCall(
[
operation
]
);

const txn = await batchCall.exec(testEnv.alice, 2);

const txReceipt = await txn.wait();
expect(txReceipt.status).to.equal(1);

const afterBalanceAlice = await testEnv.alice.getBalance();
const afterBalanceBob = await testEnv.bob.getBalance();

expect(afterBalanceBob.sub(beforeBalanceBob)).to.equal(value);
expect(beforeBalanceAlice.sub(afterBalanceAlice).gte(value)).to.be.true;
});

it("Should throw an error when multiple Operations with ETH value", async () => {
const operation1 = testEnv.sdkFramework.operation(
testEnv.alice.populateTransaction({
to: testEnv.bob.address,
value: BigNumber.from(Number(0.1e18).toString()),
data: "0x"
}) as Promise<ethers.PopulatedTransaction>,
"SIMPLE_FORWARD_CALL"
);

const operation2 = testEnv.sdkFramework.operation(
testEnv.alice.populateTransaction({
to: testEnv.bob.address,
value: BigNumber.from(Number(0.2e18).toString()),
data: "0x"
}) as Promise<ethers.PopulatedTransaction>,
"SIMPLE_FORWARD_CALL"
);

const batchCall = testEnv.sdkFramework.batchCall(
[
operation1,
operation2
]
);

await expect(batchCall.exec(testEnv.alice, 2))
.to.be.rejectedWith("multiple values in the batch call");
});
});
2 changes: 1 addition & 1 deletion packages/subgraph/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"dependencies": {
"@graphprotocol/graph-cli": "0.80.1",
"@graphprotocol/graph-ts": "0.35.1",
"@superfluid-finance/sdk-core": "0.8.0",
"@superfluid-finance/sdk-core": "0.9.0",
"mustache": "4.2.0"
},
"devDependencies": {
Expand Down
12 changes: 6 additions & 6 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -6446,10 +6446,10 @@ browserify-zlib@~0.2.0:
dependencies:
pako "~1.0.5"

[email protected].0:
version "17.0.0"
resolved "https://registry.yarnpkg.com/browserify/-/browserify-17.0.0.tgz#4c48fed6c02bfa2b51fd3b670fddb805723cdc22"
integrity sha512-SaHqzhku9v/j6XsQMRxPyBrSP3gnwmE27gLJYZgMT2GeK3J0+0toN+MnuNYDfHwVGQfLiMZ7KSNSIXHemy905w==
browserify@^17.0.1:
version "17.0.1"
resolved "https://registry.yarnpkg.com/browserify/-/browserify-17.0.1.tgz#d822fa701431ca94cb405b033bb2551951e5d97d"
integrity sha512-pxhT00W3ylMhCHwG5yfqtZjNnFuX5h2IJdaBfSo4ChaaBsIp9VLrEMQ1bHV+Xr1uLPXuNDDM1GlJkjli0qkRsw==
dependencies:
JSONStream "^1.0.3"
assert "^1.4.0"
Expand All @@ -6468,7 +6468,7 @@ [email protected]:
duplexer2 "~0.1.2"
events "^3.0.0"
glob "^7.1.0"
has "^1.0.0"
hasown "^2.0.0"
htmlescape "^1.1.0"
https-browserify "^1.0.0"
inherits "~2.0.1"
Expand Down Expand Up @@ -11083,7 +11083,7 @@ [email protected]:
resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9"
integrity sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==

has@^1.0.0, has@^1.0.3:
has@^1.0.3:
version "1.0.3"
resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796"
integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==
Expand Down

0 comments on commit afaaf81

Please sign in to comment.