Избежишь тихих обрезаний и неверных сумм в FunC: явные битовые ширины, проверки диапазона и безопасная арифметика.
Переполнение в FunC
FunC оперирует целыми произвольной точности на уровне языка, но при записи в ячейку (store_uint, store_coins) и при неверных предположениях о ширине поля значения обрезаются или падают. Ошибки типов дают неверные балансы и обойденные лимиты так же часто, как «логическая» дыра.
Уязвимо: узкий store без проверки
func (fallback highlight)
;; FunC (func 0.4.6);; УЯЗВИМО: amount из сообщения кладём в uint64 без верхней границы входных данных() recv_internal(int my_balance, int msg_value, cell in_msg_full, slice in_msg_body) impure { slice cs = in_msg_full.begin_parse(); cs~load_uint(4); slice sender_addr = cs~load_msg_addr(); int amount = in_msg_body~load_coins(); ;; дальше бизнес-логика считает, что amount «всегда разумный» ;; при сериализации в другой контракт: var payload = begin_cell() .store_uint(0x123, 32) .store_uint(amount, 64) ;; если amount не влезает — throw; если логика выше уже списала — рассинхрон .end_cell();}
tact (fallback highlight)
// @tact-lang/compiler 1.6.13// Риск рядом: Int без as-аннотации шире, чем слот в messagemessage Credit { // без `as` компилятор выберет представление; для интеропа фиксируй ширину amount: Int;}
Материалы gramdocs.tech носят образовательный характер и не являются финансовой, юридической или инвестиционной рекомендацией. Работа с блокчейном TON и токеном Gram связана с рисками потери средств. Правовая информация