Cointime

Download App
iOS & Android

Cross-Function Reentrancy Attacks in Kadena Smart Contracts

Validated Project

In this post, we briefly explain the difference between reentrancy and cross-function reentrancy, and how Turing incompleteness can prevent some such attacks. We then provide an example of a cross-function reentrancy exploit not prevented by Turing incompleteness using Pact, the programming language utilized on the Kadena blockchain.

Introduction

Kadena is a blockchain that aims to be more scalable, more secure, and easier to use than the other Layer 1 blockchains. To program smart contracts a new language has been developed: Pact. This language is made to be human readable, easily formally verified, and, to improve security: Turing incomplete. Turing incompleteness here means roughly that the Pact language is not able to do everything a Turing complete programming language such as Solidity or Haskell can do. This could look like a downside, however when it comes to smart contract programming the need for Turing completeness is quite rare, even when developing complex DeFi protocols.

One of the most important points of Turing incompleteness is the absence of unbounded recursion. While it is true that this considerably reduces the attack surface, some “classic” attacks cannot be completely prevented, as we will soon see with the cross-function reentrancy.

Classic Reentrancy

Reentrancy attacks are very common security issues. They can be hard for developers to spot, and it can be laborious for an auditor to review all the potential consequences. Reentrancy attacks depend on the order of execution of specific tasks a function makes before and after making an external call.

If a contract calls an untrusted external contract, a malicious actor can make it repeat this function call again and again, creating a recursive call. If the reentered function performs important tasks (like updating the balance of an account) this could have disastrous consequences.

Here is a simplified example:

Let’s call the vulnerable contract, unsafe contract, and the malicious contract, Attack contract.

  1. An attacker makes a call on an unsafe contract to transfer funds to the Attack contract.
  2. Receiving the call, the unsafe contract first checks to see that the attacker has the funds, then it transfers the funds to the Attack contract.
  3. Upon receiving the funds, the Attack contract executes a fallback function which calls back into an unsafe contract before it is able to update its balance, thus restarting the process.

Because this kind of attack works through an unbounded recursive call, it is impossible to carry out if the language is not Turing complete.

Cross-Function Reentrancy

Cross-function reentrancy is similar to the classic reentrancy attack, except the function reentered is not the same as the one making the external call. This kind of reentrancy attack is usually harder to spot. In complex protocols, the number of possible combinations is huge and it may be impossible to manually test each potential outcome.

This leads us to our proof of concept: a simple cross-function reentrancy attack using the Pact language.

Simple Cross-Function Reentrancy in a Pact Module

As we will see in the following code snippets, the functions in the contract make an external call to another contract implementing a specific interface. This allows a designed attack contract to reenter. The capabilities in Pact are built-in functions that grant a user privilege to perform sensitive tasks. The following pieces of code are for illustrative purposes only, they are not taken from real case contracts.

The code example we will use has three parts:

  1. The interface:

This will be used to make the main contract interact with a malicious external module.

  1. The main module:

Here is the mock contract to be exploited.

First, a database is defined as a table where a string is stored in a row with an associated decimal number.

Then a capability is defined: CREDIT (which here is always true). This condition will be required by the credit function but is only granted by the bad_function inside the with_capability statement. This implies that calling credit directly would fail.

Now, the function credit is defined: it increases the balance (the decimal) of the string given as an input. It also creates the entry if the address is not already in the table. Finally, the function bad_function increases legit_address balance but also performs a call to a contract compliant with the interface defined before, which can be provided as an input parameter.

The function get-balance allows us to read the table.

  1. The module used to exploit the reentrancy:

It reenters the main module to call the credit function.

The general flow is as follows:

a. bad_function is called with the attack contract as a parameter

b. The capability CREDIT is granted

c. The balance of “legit_address” is increased by 10

d. external_function from the malicious module is called: because this still has the capability CREDIT, it can reenter the contract and call directly the credit function to give “attacker_address” a balance of 100.

After that (get-balance “legit_address”) returns 10 and (get-balance “attacker_address”) returns 100.

The reentrancy was successful.

Now, what happens if instead of reentering to call credit we try to reenter to call bad_function again? Then, even if the first call to credit were successful, because the reentrancy would be in bad_function this would be a recursive call and the execution would not work.

Now if instead, we try to call directly external_function, this would not work because the required capability CREDIT would not be granted.

Conclusion

By removing unbounded recursivity, Turing incompleteness can prevent some reentrancy attack vectors. However, since cross-function reentrancy can be done without a recursive call, Turing incompleteness does not prevent all such attack vectors and users should not assume that reentrancy is not a problem when interacting with this kind of language.

Reentrancy and cross-function reentrancy are very common security issues that have led to some of the most costly attacks in Web3.

Pact is a promising smart contract programming language that takes a somewhat different approach to other languages like Solidity or Haskell. Pact does not rely solely on Turing incompleteness to improve security; the language is designed to be easier to read, understand, and formally verify. However, no programming language is immune to all attack vectors. It is important for developers to be aware of the unique features of the languages they work with, and for all projects to be thoroughly audited before deployment.

Read more: https://www.certik.com/resources/blog/1eFmMTGVicfAMiPka3vaTY-cross-function-reentrancy-attacks-in-kadena-smart-contracts

Comments

All Comments

Recommended for you

  • Global Bond Market Faces Sell-off, Panda Bond Issuance Reaches Record High

    According to CCTV Finance, the long-term government bond yields of major global economies have continued to rise recently, intensifying sell-off pressure in the bond market. However, China's bond market and exchange rate have remained relatively stable, with the issuance of Panda bonds reaching a historical high for the same period. Data shows that as of August 21, the cumulative issuance of 2026 Panda bonds has reached 209.975 billion yuan, an increase of over 73% year-on-year. Against the backdrop of significant fluctuations in the global bond market, the increased interest from international institutions in domestic RMB financing has drawn attention. Industry insiders noted, 'We are in completely different economic and monetary cycles compared to overseas. Foreign capital accounts for only about 5%-8% of our bond market, while domestic capital holds absolute pricing power. Coupled with our monetary policy that prioritizes domestic considerations, overseas shocks cannot reverse the overall trend of the domestic bond market.' Looking ahead, industry experts believe that overseas bond yields are likely to remain highly volatile, highlighting the value of RMB bond allocations, and foreign capital may continue to increase its allocation in the medium to long term. However, it is also important to note that rising U.S. bond yields have raised the return threshold for global allocation funds, which may disrupt the willingness of foreign institutions to increase their holdings of RMB bonds. Additionally, the rapid rise in bond yields in developed countries overseas may also constrain the valuation of domestic risk assets.

  • Global Bond Market Faces Sell-Off, Panda Bond Issuance Reaches Record High

    According to CCTV Finance, recent long-term government bond yields in major global economies have been rising, increasing sell-off pressure in the bond market. In contrast, China's bond market and exchange rate have remained relatively stable, with Panda bond issuance reaching a historical high for the same period. Data shows that as of August 21, the cumulative issuance of 2026 Panda bonds has reached 209.975 billion yuan, a year-on-year increase of over 73%. Amidst significant fluctuations in the global bond market, international institutions are increasingly focusing on domestic RMB financing. Industry insiders noted, 'We are in completely different economic and monetary cycles compared to overseas. Foreign capital accounts for only about 5%-8% of our bond market, while domestic capital holds absolute pricing power. Coupled with our monetary policy that prioritizes domestic conditions, overseas shocks cannot reverse the overall trend of the domestic bond market.' Looking ahead, industry experts believe that overseas bond yields are likely to remain highly volatile, highlighting the value of RMB bond allocation, which may attract continued foreign investment in the medium to long term. However, it is also important to note that rising U.S. bond yields have raised the return threshold for global allocation funds, which may disturb the willingness of foreign institutions to increase their holdings of RMB bonds. Additionally, the rapid rise in yields of bonds from developed countries overseas may also constrain the valuation of domestic risk assets.

  • Whale Transfers 1,727 Bitcoins Worth $133 Million to Binance

    According to monitoring by Bitcoin News, a whale has transferred 1,727 bitcoins, valued at $133 million, to Binance.

  • A Whale Transfers 1,727 Bitcoins Worth $133 Million to Binance

    According to monitoring by Bitcoin News, a whale has transferred 1,727 bitcoins to Binance, valued at $133 million.

  • Canadian Prime Minister: Tariff Measures Against the U.S. to Take Effect on September 8

    On August 22, Canadian Prime Minister Carney announced that Canada's tariff measures against the United States will take effect on September 8. (Jin Ten)

  • Canadian Prime Minister: Tariff Measures Against the U.S. to Take Effect on September 8

    On August 22, Canadian Prime Minister Carney announced that Canada’s tariff measures against the United States will take effect on September 8. (Jin Shi)

  • Over $1.244 Billion Liquidated in 24 Hours, Majority in Long Positions

    On August 22, according to CoinGlass data, the total liquidation amount in the cryptocurrency market reached $1.244 billion in the past 24 hours, with long positions accounting for $744 million and short positions for $500 million. A total of 246,203 individuals were liquidated. Among them, the liquidation amount for BTC was approximately $194 million, for ETH about $277 million, for SOL around $104 million, for XRP about $123 million, for ZEC approximately $66.77 million, and other assets totaled about $479 million in liquidations. The largest single liquidation in the past 24 hours occurred on the BTC-USD trading pair on Hyperliquid, valued at approximately $24.96 million.

  • Over $1.244 Billion Liquidated in the Last 24 Hours, Primarily Long Positions

    On August 22, according to CoinGlass data, the total liquidation amount in the cryptocurrency market over the past 24 hours reached $1.244 billion, with long positions accounting for $744 million and short positions for $500 million. A total of 246,203 individuals were liquidated. Among them, the liquidation amounts were approximately $194 million for BTC, $277 million for ETH, $104 million for SOL, $123 million for XRP, and about $66.77 million for ZEC, with other assets totaling approximately $479 million in liquidations. The largest single liquidation occurred on the Hyperliquid BTC-USD trading pair, valued at approximately $24.96 million.

  • Grayscale: Bitcoin May Have Hit Bottom, This Week's Rise Signals Key Cycle Reversal

    On August 22, Grayscale published an article indicating that this week could mark a turning point for Bitcoin. Historical data shows that Bitcoin typically bottoms out after falling about 80% from its cycle peak. In the recent bear market, Bitcoin has dropped about 50% from its cycle high, which is less than in all previous cycles up to this point. There has been ongoing market speculation about whether Bitcoin will experience a new round of declines in the fourth quarter of 2026. Although risks remain in the market, this week's rise may suggest that Bitcoin has formed a more solid bottom.

  • Grayscale: Bitcoin May Have Reached Bottom, This Week's Rise is a Key Signal for Cycle Reversal

    On August 22, Grayscale published a statement indicating that this week could mark a turning point for Bitcoin. Historical data shows that Bitcoin typically bottoms out after falling about 80% from its cycle peak. In the recent bear market, Bitcoin has dropped about 50% from its cycle high, which is less than the declines seen in all previous cycles. There has been ongoing market speculation about whether Bitcoin will experience a new downturn in the fourth quarter of 2026. Although risks remain in the market, this week's rise may suggest that Bitcoin has formed a more solid bottom.