TGViewer
Из Solidity в AI и дальше Из Solidity в AI и дальше @solidityset · 2.48K subscribers
Post #749 568
Необычная функция

Просто хочу поделиться необычной логикой работы функции, которую я вчера встретил в аудите. За все время обучения лично я столкнулся с этим впервые, что вызвало некоторые недоумения.

Я постараюсь разложить ее "по полочкам". Итак, вот сам контракт, если вдруг кому будет интересно.

И там есть такая функция (я ее обрезал, убрав не интересные части):

function stake (
AssetType _assetType,
uint256 _timelockId,
uint256,
uint256,
uint256
) external nonReentrant {

uint256 timelockOption = timelockOptions[_assetType][_timelockId];

function (uint256) _s1 = _stakeS1Citizen;
function (uint256) _s2 = _stakeS2Citizen;
function (uint256) _b = _stakeBytes;
function (uint256) _lp = _stakeLP;

function (uint256) _stake;

assembly {
switch _assetType
case 0 {
_stake := _s1
}
case 1 {
_stake := _s2
}
case 2 {
_stake := _b
}
case 3 {
_stake := _lp
}
default {}
}

_stake(timelockOption);
}

Возможно, для опытным разработчиков она окажется простой, но для других - интересным опытом.

Обратите внимание, что в параметрах функции 5 аргументов, 3 из которых обозначены просто как тип uint256 без переменных.

Далее, я не совсем разобрался, как называется это действие, но мы создаем некие поинтеры на другие функции в контракте и кладем их в переменные _s1, _s2, _b, _lp.

_stakeS1Citizen, _stakeS2Citizen, _stakeBytes, _stakeLP - да, это все функции в данном контракте, например:

function _stakeS1Citizen (uint256 _timelock) private {}

Также нужно учесть, что в данном примере, один из аргументов в функции, assetType - это enum. Вот как он выглядит:

enum AssetType {S1_CITIZEN, S2_CITIZEN, BYTES, LP}

Т.е. вы поняли, что происходит в функции?

Мы создали поинтеры на другие функции в контракте, а затем через assembler прогнались по enum и переопределили в поинтер _stake необходимую для нас опцию!

Другими словами, исполнение данной функции продолжится уже в другой функции, учитывая значения AssetType!

Дальше еще круче!

Помните те 3 безыменных аргумента uint256 в функции?

Они передаются в последующие функции, как calldata! Например, одна из функция такая:

function _stakeBytes (uint256) ) private {

uint256 amount;
uint256 citizenId;
uint256 seasonId;

assembly{
amount := calldataload(0x44)
citizenId := calldataload(0x64)
seasonId := calldataload(0x84)
}

}

Эта calldata из безымянных uint256 передается в другие функции и расшифровывается в assembly. И что самое интересное, во всех 4 функциях _stakeS1Citizen, _stakeS2Citizen, _stakeBytes, _stakeLP - расшифровываются разные calldata в зависимости от полученных в главное функции stake!

В общем, меня впечатлил данный контракт! Надеюсь и вам он понравится.

#function
  • 👍 7
  • 🤯 1
More from @solidityset
  1. Oct 2, 2026Вторая сложность — как доказать, что установилось именно опубликованное. В первом варианте…
  2. Oct 2, 2026Задача с полуоткрытым кодом На днях, в процессе создания одного приложения, столкнулся с и…
  3. Sep 22, 2026Какой язык программирования учить сейчас? На днях в Твиттере увидел небольшой пост о разви…
  4. Sep 18, 2026Интересная модель Jev Буквально пару дней назад в Твиттере многие начали обсуждение новой…
  5. Sep 14, 2026Графы повсюду Если вы также следите за новостями в мире ИИ, то наверняка уже все чаще встр…
  6. Sep 10, 2026GTA6, Cyberleek, блокчейн и безопасность Увидел несколько постов (тут и тут) про Cyberleek…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →