#ethereum #solidity
Вопрос:
это часть моего кода (часть токеновых контрактов):
contract SpeadTheGainContract{
uint public _totalSupply;
mapping(address => uint) public balances;
uint public indexedAddressesCounter = 0;
mapping(address=>bool) ifAdressExisted;
mapping(uint=>address) ownersAddresses;
uint requiredAmount = 1 wei;
function spreadTheGain() external{
for (uint i = 0; i < indexedAddressesCounter; i ){
payable(ownersAddresses[i]).transfer(address(this).balance*(balances[ownersAddresses[i]]/_totalSupply));
}
}
function increaseValue() external payable{
require(msg.value >= requiredAmount, "Can't send 0 value!");
}
}
При каждой передаче токена будет добавляться новый адрес получателя . ownersAddresses
С increaseValue()
помощью контракта получает количество ETH и сохраняет его.
При spreadTheGain()
этом сохраненный ETH контракта будет распределен между держателями токенов.
Проблема в том, что он отлично работает, когда есть 1 держатель токена (владелец), но если есть еще один, он не работает и выполняет функцию без какой-либо отправки ETH.
В деталях транзакции указывается сумма внутренней транзакции держателей с отправкой ETH держателям, но значение отправки равно 0 ETH.
В чем проблема?!
Ответ №1:
Есть две проблемы:
- После каждой передачи баланс контракта обновляется
address(this).balance.
, поэтому, если вы хотите разделить 10 wei между 10 адресами, первый будет видеть 10 wei/10, а второй-9 wei /10. - Целочисленное деление в солидности усекает результат, поэтому 9/10 возвращает 0. Расчеты делают
EtherBalance * (TokenBalance / TotalSupply)
. Когда имеется более 1 держателяTokenBalance < TotalSupply
иTokenBalance / TotalSupply = 0
.
Чтобы решить первую проблему, сохраните баланс в переменной перед входом в цикл. Вторая проблема может быть решена путем изменения порядка операций, сначала выполняющих продукт, а затем разделение (EtherBalance * TokenBalance) / TotalSupply
.
function spreadTheGain() external {
uint256 totalBalance = address(this).balance;
for (uint i = 0; i < indexedAddressesCounter; i ) {
uint256 amount = (totalBalance * balances[ownersAddresses[i]]) / _totalSupply;
payable(ownersAddresses[i]).transfer(amount);
}
}