Разделение стоимости контракта (на самом деле это контракт на токены) между держателями

#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:

Есть две проблемы:

  1. После каждой передачи баланс контракта обновляется address(this).balance. , поэтому, если вы хотите разделить 10 wei между 10 адресами, первый будет видеть 10 wei/10, а второй-9 wei /10.
  2. Целочисленное деление в солидности усекает результат, поэтому 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);
    }
}