Skip to content

Commit 3b28de6

Browse files
committed
- Test slices decoding added
- PR fixed
1 parent 723e4d7 commit 3b28de6

File tree

2 files changed

+104
-1
lines changed

2 files changed

+104
-1
lines changed

Sources/Web3Core/EthereumABI/ABIElements.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -410,7 +410,7 @@ extension ABI.Element.Function {
410410

411411
if data.count >= 4,
412412
let errors = errors,
413-
let customError = errors[data[data.indices.startIndex + 0 ..< data.indices.startIndex + 4].toHexString().stripHexPrefix()] {
413+
let customError = errors[data[data.indices.startIndex ..< data.indices.startIndex + 4].toHexString().stripHexPrefix()] {
414414
var errorResponse: [String: Any] = ["_success": false, "_abortedByRevertOrRequire": true, "_error": customError.errorDeclaration]
415415

416416
if (data.count > 32 && !customError.inputs.isEmpty),
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
//
2+
// ABIDecoderSliceTests.swift
3+
// localTests
4+
//
5+
// Created by 6od9i on 24.03.2023.
6+
//
7+
8+
import Foundation
9+
import Web3Core
10+
import XCTest
11+
import BigInt
12+
@testable import web3swift
13+
14+
final class ABIDecoderSliceTests: XCTestCase {
15+
func testBallancesDataSlice() throws {
16+
/// Arrange
17+
let balanceofMethod = try EthereumContract(Web3.Utils.erc20ABI).methods["balanceOf"]!.first!
18+
let correctValues = ["13667129429770787859", "3298264", "47475", "19959", "607690442193821", "999170411478050086"]
19+
let hex6Responses =
20+
"000000000000000000000000000000000000000000000000bdab65ce08c65c1300000000000000000000000000000000000000000000000000000000003253d8000000000000000000000000000000000000000000000000000000000000b9730000000000000000000000000000000000000000000000000000000000004df7000000000000000000000000000000000000000000000000000228b0f4f0bb9d0000000000000000000000000000000000000000000000000dddc432063ae526"
21+
let data = Data(hex: hex6Responses)
22+
let answerSize = 32
23+
var startIndex = 0
24+
var results = [String]()
25+
26+
/// Act
27+
while startIndex < data.count {
28+
let slice = data[startIndex ..< startIndex + answerSize]
29+
startIndex += answerSize
30+
guard let bigInt = balanceofMethod.decodeReturnData(slice)["0"] as? BigUInt else {
31+
throw Web3Error.processingError(desc: "Can not decode returned parameters")
32+
}
33+
let value = Utilities.formatToPrecision(bigInt, units: .wei)
34+
results.append(value)
35+
}
36+
37+
/// Assert
38+
XCTAssertEqual(correctValues, results)
39+
}
40+
41+
func testDecodeMulticallDifferentValues() async throws {
42+
/// Arrange
43+
let multiCall2Contract = try EthereumContract(Self.multiCall2, at: nil)
44+
let differentRequestsContract = try EthereumContract(Self.differentRequestsContract, at: nil)
45+
46+
let data = Data(hex: "0000000000000000000000000000000000000000000000000000000001980dd40000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000001af3f329e8be154074d8769d1ffa4ee058b1dbc3000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000038d7ea4c68000000000000000000000000000000000000000000000000000000000006358d8a5000000000000000000000000000000000000000000000000000000007628d02500000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000212295b818158b400000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000")
47+
48+
let methods = [differentRequestsContract.methods["arrayValue"]?.first,
49+
differentRequestsContract.methods["firstValue"]?.first,
50+
differentRequestsContract.methods["secondValue"]?.first].compactMap({$0})
51+
52+
XCTAssertEqual(methods.count, 3)
53+
54+
/// Act
55+
guard let decodedData = multiCall2Contract.decodeReturnData("aggregate", data: data) else {
56+
throw Web3Error.processingError(desc: "Can not decode returned parameters")
57+
}
58+
59+
guard let returnData = decodedData["returnData"] as? [Data] else {
60+
throw Web3Error.dataError
61+
}
62+
63+
XCTAssertEqual(returnData.count, 3)
64+
65+
for item in methods.enumerated() {
66+
XCTAssertNotNil(item.element.decodeReturnData(returnData[item.offset])["0"])
67+
}
68+
}
69+
70+
func testDecodeMulticallCopy() throws {
71+
/// Arrange
72+
let data = Data(hex: "0x00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000004fe6dab4abca350650")
73+
let contract = try EthereumContract(Self.multiCall2, at: nil)
74+
let erc20_balanceof = try EthereumContract(Web3.Utils.erc20ABI).methods["balanceOf"]!.first!
75+
76+
/// Act
77+
guard let decodedData = contract.decodeReturnData("tryAggregate", data: data) else {
78+
throw Web3Error.processingError(desc: "Can not decode returned parameters")
79+
}
80+
81+
guard let returnData = decodedData["returnData"] as? [[Any]] else {
82+
throw Web3Error.dataError
83+
}
84+
var resultArray = [BigUInt]()
85+
for i in 0..<2 {
86+
guard let data = returnData[i][1] as? Data,
87+
let balance = erc20_balanceof.decodeReturnData(data)["0"] as? BigUInt else {
88+
resultArray.append(0)
89+
continue
90+
}
91+
resultArray.append(balance)
92+
}
93+
94+
/// Assert
95+
XCTAssert(resultArray.count == 2)
96+
}
97+
}
98+
99+
extension ABIDecoderSliceTests {
100+
public static let differentRequestsContract = "[{\"inputs\":[],\"name\":\"firstValue\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"arrayValue\",\"outputs\":[{\"internalType\":\"contract IERC20\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"enum IInstanceV1.Period\",\"name\":\"period\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"startTime\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"endTime\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"secondValue\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]"
101+
102+
public static let multiCall2 = "[{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"callData\",\"type\":\"bytes\"}],\"internalType\":\"struct Multicall2.Call[]\",\"name\":\"calls\",\"type\":\"tuple[]\"}],\"name\":\"aggregate\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"blockNumber\",\"type\":\"uint256\"},{\"internalType\":\"bytes[]\",\"name\":\"returnData\",\"type\":\"bytes[]\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"callData\",\"type\":\"bytes\"}],\"internalType\":\"struct Multicall2.Call[]\",\"name\":\"calls\",\"type\":\"tuple[]\"}],\"name\":\"blockAndAggregate\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"blockNumber\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"blockHash\",\"type\":\"bytes32\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"returnData\",\"type\":\"bytes\"}],\"internalType\":\"struct Multicall2.Result[]\",\"name\":\"returnData\",\"type\":\"tuple[]\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"blockNumber\",\"type\":\"uint256\"}],\"name\":\"getBlockHash\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"blockHash\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getBlockNumber\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"blockNumber\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getCurrentBlockCoinbase\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"coinbase\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getCurrentBlockDifficulty\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"difficulty\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getCurrentBlockGasLimit\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"gaslimit\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getCurrentBlockTimestamp\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"timestamp\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"}],\"name\":\"getEthBalance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"balance\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getLastBlockHash\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"blockHash\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bool\",\"name\":\"requireSuccess\",\"type\":\"bool\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"callData\",\"type\":\"bytes\"}],\"internalType\":\"struct Multicall2.Call[]\",\"name\":\"calls\",\"type\":\"tuple[]\"}],\"name\":\"tryAggregate\",\"outputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"returnData\",\"type\":\"bytes\"}],\"internalType\":\"struct Multicall2.Result[]\",\"name\":\"returnData\",\"type\":\"tuple[]\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bool\",\"name\":\"requireSuccess\",\"type\":\"bool\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"callData\",\"type\":\"bytes\"}],\"internalType\":\"struct Multicall2.Call[]\",\"name\":\"calls\",\"type\":\"tuple[]\"}],\"name\":\"tryBlockAndAggregate\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"blockNumber\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"blockHash\",\"type\":\"bytes32\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"returnData\",\"type\":\"bytes\"}],\"internalType\":\"struct Multicall2.Result[]\",\"name\":\"returnData\",\"type\":\"tuple[]\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]"
103+
}

0 commit comments

Comments
 (0)