COOPENOMICS  v1
Кооперативная Экономика
global_state.hpp
См. документацию.
1#pragma once
2
3
4#include "../../../lib/core/ram_payer.hpp"
5#include <eosio/binary_extension.hpp>
6
7using namespace eosio;
8using std::string;
9
10namespace Capital {
11
15 // Значения по умолчанию держатся В СООТВЕТСТВИИ с defaultConfig бэкенда
16 // (controller/src/extensions/capital/capital-extension.module.ts): именно он
17 // задаёт конфигурацию кооперативу при онбординге, а эти значения работают
18 // ровно до неё. Пока они расходились, кооператив без явной настройки жил по
19 // другим правилам, чем показывал интерфейс.
20 struct config {
22 double expense_pool_percent = 100;
24 uint32_t voting_period_in_days = 1;
25 double authors_voting_percent = 62.8;
27
28 // Параметры геймификации
30 uint64_t level_depth_base = 100000000;
33 };
34
43 struct [[eosio::table, eosio::contract(CAPITAL)]] global_state {
44 eosio::name coopname;
45 asset global_available_invest_pool = asset(0, _root_govern_symbol);
46 asset program_membership_funded = asset(0, _root_govern_symbol);
47 asset program_membership_available = asset(0, _root_govern_symbol);
48 asset program_membership_distributed = asset(0, _root_govern_symbol);
50
52
53 // ВНИМАНИЕ: поля программных расходов добавлены ПОСЛЕ config и обёрнуты в
54 // binary_extension. Поля в таблицу EOSIO можно дописывать только в ХВОСТ
55 // struct и только через binary_extension — иначе ломается десериализация
56 // уже записанного global_state. Инцидент 2026-06-16: эти поля были вставлены
57 // перед config напрямую (без extension) и задеплоены на прод — таблица state
58 // перестала читаться (get table → "Invalid symbol", action'ы падали на unpack).
59 // Инвариант: оба поля материализуются вместе (всегда оба has_value или оба
60 // пустые), чтобы порядок хвостовых extension оставался консистентным.
61 eosio::binary_extension<asset> program_expense_pool;
62 eosio::binary_extension<asset> program_expense_reserved;
63
64 uint64_t primary_key() const { return coopname.value; }
65 };
66
67 typedef eosio::multi_index<"state"_n, global_state> global_state_table;
68
69
70
71
72namespace State {
73
82inline asset ext_or_zero(const eosio::binary_extension<asset>& v, const eosio::symbol& sym) {
83 if (!v.has_value()) {
84 return asset(0, sym);
85 }
86 const asset &a = v.value();
87 if (a.symbol == sym) {
88 return a;
89 }
90 eosio::check(a.amount == 0,
91 "program_expense_* содержит ненулевую сумму с несовместимым символом");
92 return asset(0, sym);
93}
94
102inline void update_global_state(const global_state& gs){
103 global_state_table global_state_inst(_capital, _capital.value);
104 auto itr = global_state_inst.find(gs.coopname.value);
105 check(itr != global_state_inst.end(), "Глобальное состояние не найдено");
107 const asset reserved = ext_or_zero(gs.program_expense_reserved, _root_govern_symbol);
108 global_state_inst.modify(itr, RamPayer::of(global_state_inst), [&](auto& s) {
109 s = gs;
110 s.program_expense_pool = pool;
111 s.program_expense_reserved = reserved;
112 });
113}
114
120inline global_state get_global_state(name coopname) {
121 global_state_table global_state_inst(_capital, _capital.value);
122 auto itr = global_state_inst.find(coopname.value);
123 eosio::check(itr != global_state_inst.end(), "Контракт не инициализирован");
124 return global_state(*itr);
125}
126
132inline void is_initialized(name coopname) {
133 global_state_table global_state_inst(_capital, _capital.value);
134 auto itr = global_state_inst.find(coopname.value);
135 eosio::check(itr != global_state_inst.end(), "Контракт не инициализирован");
136}
137
142inline void topup_program_expense_pool(eosio::name coopname, const asset &amount) {
143 global_state_table global_state_inst(_capital, _capital.value);
144 auto itr = global_state_inst.find(coopname.value);
145 eosio::check(itr != global_state_inst.end(), "Контракт не инициализирован");
146 eosio::check(amount.is_valid() && amount.amount > 0, "Сумма пополнения должна быть положительной");
147 eosio::check(amount.symbol == _root_govern_symbol, "Символ суммы пополнения должен совпадать с символом программы");
148 eosio::check(itr->global_available_invest_pool >= amount,
149 "Недостаточно свободных инвестиций программы для пополнения пула расходов");
150
151 global_state_inst.modify(itr, RamPayer::of(global_state_inst), [&](auto &s) {
152 asset pool = ext_or_zero(s.program_expense_pool, amount.symbol);
153 asset reserved = ext_or_zero(s.program_expense_reserved, amount.symbol);
154 s.global_available_invest_pool -= amount;
155 pool += amount;
156 s.program_expense_pool = pool;
157 s.program_expense_reserved = reserved;
158 });
159}
160
165inline void reserve_program_expense(eosio::name coopname, const asset &amount) {
166 global_state_table global_state_inst(_capital, _capital.value);
167 auto itr = global_state_inst.find(coopname.value);
168 eosio::check(itr != global_state_inst.end(), "Контракт не инициализирован");
169 eosio::check(amount.is_valid() && amount.amount > 0, "Сумма резерва должна быть положительной");
170 eosio::check(ext_or_zero(itr->program_expense_pool, amount.symbol) >= amount,
171 "Недостаточно средств в пуле программных расходов");
172
173 global_state_inst.modify(itr, RamPayer::of(global_state_inst), [&](auto &s) {
174 asset pool = ext_or_zero(s.program_expense_pool, amount.symbol);
175 asset reserved = ext_or_zero(s.program_expense_reserved, amount.symbol);
176 pool -= amount;
177 reserved += amount;
178 s.program_expense_pool = pool;
179 s.program_expense_reserved = reserved;
180 });
181}
182
187inline void release_program_expense(eosio::name coopname, const asset &amount) {
188 global_state_table global_state_inst(_capital, _capital.value);
189 auto itr = global_state_inst.find(coopname.value);
190 eosio::check(itr != global_state_inst.end(), "Контракт не инициализирован");
191 eosio::check(amount.is_valid() && amount.amount > 0, "Сумма освобождения должна быть положительной");
192 eosio::check(ext_or_zero(itr->program_expense_reserved, amount.symbol) >= amount,
193 "Зарезервированных программных расходов меньше указанной суммы");
194
195 global_state_inst.modify(itr, RamPayer::of(global_state_inst), [&](auto &s) {
196 asset pool = ext_or_zero(s.program_expense_pool, amount.symbol);
197 asset reserved = ext_or_zero(s.program_expense_reserved, amount.symbol);
198 reserved -= amount;
199 pool += amount;
200 s.program_expense_pool = pool;
201 s.program_expense_reserved = reserved;
202 });
203}
204
210inline void consume_program_expense(eosio::name coopname, const asset &amount) {
211 global_state_table global_state_inst(_capital, _capital.value);
212 auto itr = global_state_inst.find(coopname.value);
213 eosio::check(itr != global_state_inst.end(), "Контракт не инициализирован");
214 eosio::check(amount.is_valid() && amount.amount > 0, "Сумма списания должна быть положительной");
215 eosio::check(ext_or_zero(itr->program_expense_reserved, amount.symbol) >= amount,
216 "Зарезервированных программных расходов меньше указанной суммы");
217
218 global_state_inst.modify(itr, RamPayer::of(global_state_inst), [&](auto &s) {
219 asset pool = ext_or_zero(s.program_expense_pool, amount.symbol);
220 asset reserved = ext_or_zero(s.program_expense_reserved, amount.symbol);
221 reserved -= amount;
222 s.program_expense_pool = pool;
223 s.program_expense_reserved = reserved;
224 });
225}
226
232inline void spend_program_expense_pool(eosio::name coopname, const asset &amount) {
233 global_state_table global_state_inst(_capital, _capital.value);
234 auto itr = global_state_inst.find(coopname.value);
235 eosio::check(itr != global_state_inst.end(), "Контракт не инициализирован");
236 eosio::check(amount.is_valid() && amount.amount > 0, "Сумма списания должна быть положительной");
237 eosio::check(ext_or_zero(itr->program_expense_pool, amount.symbol) >= amount,
238 "Недостаточно средств в пуле программных расходов для покрытия перерасхода — пополните пул (topupprogexp)");
239
240 global_state_inst.modify(itr, RamPayer::of(global_state_inst), [&](auto &s) {
241 asset pool = ext_or_zero(s.program_expense_pool, amount.symbol);
242 asset reserved = ext_or_zero(s.program_expense_reserved, amount.symbol);
243 pool -= amount;
244 s.program_expense_pool = pool;
245 s.program_expense_reserved = reserved;
246 });
247}
248}// namespace State
249
250}// namespace Capital
251
252// Плательщик за оперативную память строк таблицы — правило в lib/core/ram_payer.hpp.
static constexpr eosio::name _capital
Definition: consts.hpp:171
static constexpr eosio::symbol _root_govern_symbol
Definition: consts.hpp:236
contract
Definition: eosio.msig_tests.cpp:977
share_type amount
Definition: eosio.token_tests.cpp:174
RAM_PAYER_CLASS(Capital::global_state, contract)
void release_program_expense(eosio::name coopname, const asset &amount)
Освобождает зарезервированное при отклонении программного расхода: program_expense_reserved -= amount...
Definition: global_state.hpp:187
void consume_program_expense(eosio::name coopname, const asset &amount)
Окончательное списание программного расхода (callback onpgexpdone, CLOSED): program_expense_reserved ...
Definition: global_state.hpp:210
global_state get_global_state(name coopname)
Получает текущее глобальное состояние.
Definition: global_state.hpp:120
asset ext_or_zero(const eosio::binary_extension< asset > &v, const eosio::symbol &sym)
Значение binary_extension<asset> или ноль с символом sym.
Definition: global_state.hpp:82
void reserve_program_expense(eosio::name coopname, const asset &amount)
Резервирует средства под approved/authorized программный расход: program_expense_pool -= amount,...
Definition: global_state.hpp:165
void is_initialized(name coopname)
Проверяет что контракт инициализирован.
Definition: global_state.hpp:132
void update_global_state(const global_state &gs)
Обновляет глобальное состояние новыми значениями.
Definition: global_state.hpp:102
void spend_program_expense_pool(eosio::name coopname, const asset &amount)
Прямое списание из свободного пула программных расходов — превышение факта над резервом при закрытии ...
Definition: global_state.hpp:232
void topup_program_expense_pool(eosio::name coopname, const asset &amount)
Пополняет пул программных расходов на amount из общего пула инвестиций программы. Вызывается из actio...
Definition: global_state.hpp:142
Definition: balances.cpp:6
eosio::multi_index<"state"_n, global_state > global_state_table
Таблица для хранения глобального состояния.
Definition: global_state.hpp:67
eosio::name of(const Table &table, eosio::name coopname)
Definition: ram_payer.hpp:78
Definition: eosio.msig.hpp:34
Конфигурация контракта, управляемая пользователем.
Definition: global_state.hpp:20
double energy_decay_rate_per_day
Скорость уменьшения энергии в день
Definition: global_state.hpp:29
uint32_t voting_period_in_days
Период голосования в днях
Definition: global_state.hpp:24
double creators_voting_percent
Процент премий создателей для голосования
Definition: global_state.hpp:26
double authors_voting_percent
Процент премий авторов для голосования
Definition: global_state.hpp:25
double coordinator_bonus_percent
Процент премий координатора от инвестиций
Definition: global_state.hpp:21
double expense_pool_percent
Процент инвестиций в пул расходов
Definition: global_state.hpp:22
double energy_gain_coefficient
Множитель скорости набора уровней (по умолчанию 1.0 — вклад размером level_depth_base даёт ровно один...
Definition: global_state.hpp:32
uint32_t coordinator_invite_validity_days
Срок действия приглашения координатора (дней)
Definition: global_state.hpp:23
uint64_t level_depth_base
Базовая сумма вкладов для уровня 1 (10000 RUB при точности рубля 4 знака: 10000 × 10^4)
Definition: global_state.hpp:30
double level_growth_coefficient
Коэффициент роста требований для следующих уровней (по умолчанию 1.5)
Definition: global_state.hpp:31
Таблица глобального состояния хранит общие данные контракта благороста.
Definition: global_state.hpp:43
eosio::binary_extension< asset > program_expense_pool
Доступная сумма программы под целевые расходы (без аллокации в проекты)
Definition: global_state.hpp:61
eosio::name coopname
Имя кооператива
Definition: global_state.hpp:44
double program_membership_cumulative_reward_per_share
Накопительное вознаграждение на долю в членских взносах
Definition: global_state.hpp:49
config config
Управляемая конфигурация контракта
Definition: global_state.hpp:51
uint64_t primary_key() const
Первичный ключ (1)
Definition: global_state.hpp:64
eosio::binary_extension< asset > program_expense_reserved
Сумма, зарезервированная под approved/authorized программные расходы
Definition: global_state.hpp:62