MCPcopy Create free account
hub / github.com/argotorg/solidity / abiDecodingFunctionStruct

Method abiDecodingFunctionStruct

libsolidity/codegen/ABIFunctions.cpp:1328–1391  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

1326}
1327
1328std::string ABIFunctions::abiDecodingFunctionStruct(StructType const& _type, bool _fromMemory)
1329{
1330 solAssert(!_type.dataStoredIn(DataLocation::CallData), "");
1331 std::string functionName =
1332 "abi_decode_" +
1333 _type.identifier() +
1334 (_fromMemory ? "_fromMemory" : "");
1335
1336 return createFunction(functionName, [&]() {
1337 Whiskers templ(R"(
1338 // <readableTypeName>
1339 function <functionName>(headStart, end) -> value {
1340 if slt(sub(end, headStart), <minimumSize>) { <revertString>() }
1341 value := <allocate>(<memorySize>)
1342 <#members>
1343 {
1344 // <memberName>
1345 <decode>
1346 }
1347 </members>
1348 }
1349 )");
1350 // TODO add test
1351 templ("revertString", revertReasonIfDebugFunction("ABI decoding: struct data too short"));
1352 templ("functionName", functionName);
1353 templ("readableTypeName", _type.toString(true));
1354 templ("allocate", m_utils.allocationFunction());
1355 solAssert(_type.memoryDataSize() < u256("0xffffffffffffffff"), "");
1356 templ("memorySize", toCompactHexWithPrefix(_type.memoryDataSize()));
1357 size_t headPos = 0;
1358 std::vector<std::map<std::string, std::string>> members;
1359 for (auto const& member: _type.members(nullptr))
1360 {
1361 solAssert(member.type, "");
1362 solAssert(!member.type->containsNestedMapping(), "");
1363 auto decodingType = member.type->decodingType();
1364 solAssert(decodingType, "");
1365 Whiskers memberTempl(R"(
1366 <?dynamic>
1367 let offset := <load>(add(headStart, <pos>))
1368 if gt(offset, 0xffffffffffffffff) { <revertString>() }
1369 <!dynamic>
1370 let offset := <pos>
1371 </dynamic>
1372 mstore(add(value, <memoryOffset>), <abiDecode>(add(headStart, offset), end))
1373 )");
1374 memberTempl("dynamic", decodingType->isDynamicallyEncoded());
1375 // TODO add test
1376 memberTempl("revertString", revertReasonIfDebugFunction("ABI decoding: invalid struct offset"));
1377 memberTempl("load", _fromMemory ? "mload" : "calldataload");
1378 memberTempl("pos", std::to_string(headPos));
1379 memberTempl("memoryOffset", toCompactHexWithPrefix(_type.memoryOffsetOfMember(member.name)));
1380 memberTempl("abiDecode", abiDecodingFunction(*member.type, _fromMemory, false));
1381
1382 members.emplace_back();
1383 members.back()["decode"] = memberTempl.render();
1384 members.back()["memberName"] = member.name;
1385 headPos += decodingType->calldataHeadSize();

Callers 1

conversionFunctionMethod · 0.80

Calls 14

createFunctionFunction · 0.85
toCompactHexWithPrefixFunction · 0.85
identifierMethod · 0.80
allocationFunctionMethod · 0.80
memoryOffsetOfMemberMethod · 0.80
renderMethod · 0.80
calldataHeadSizeMethod · 0.80
to_stringFunction · 0.50
dataStoredInMethod · 0.45
toStringMethod · 0.45
memoryDataSizeMethod · 0.45
containsNestedMappingMethod · 0.45

Tested by

no test coverage detected