Below I extracted the logic which calls a remote contract to calculate the amount of tokens to withdraw funds.
contact Example {
mapping (address => uint256) balances;
ERC20 token = ...; // remote token contract
uint256 contract_eth_value = ...;
...
function () payable {
// User's address.
address user = msg.sender;
// Retrieve current token balance of contract.
// HERE !!!!!!!!!!!!!!!!!!!!!!!!!
uint256 contract_token_balance = token.balanceOf(address(this));
// Disallow token withdrawals if there are no tokens to withdraw.
uint256 tokens_to_withdraw = (balances[user] * contract_token_balance) / contract_eth_value;
// Update the value of tokens currently held by the contract.
contract_eth_value -= balances[user];
// Update the user's balance prior to sending to prevent recursive call.
balances[user] = 0;
// Send the funds. Throws on failure to prevent loss of funds.
if(!token.transfer(user, tokens_to_withdraw)) throw;
}
}
I've searched solidity documentation for an answer but with no success. What I'm wondering or better what I'm afraid about is that when a call to a remote contract is executed, the contract function looses atomicity. If what I'm saying is true then the call above could lead to race conditions and thus unexpected results. This case would certainly be non-atomic in some distributed databases but I'm not sure if that also stands for Ethereum-based applications (contracts).
I would appreciate if an expert could take some time and explain this situation in details. A link to the official documentation/statement on that is also welcome.
UPDATE: I found a similar debate here

