make unnesassary result

This commit is contained in:
Alex Ant
2025-03-26 11:42:05 +05:00
parent 9d03694ea7
commit a0ad71a524
44 changed files with 1147 additions and 1149 deletions
+6
View File
@@ -120,6 +120,12 @@ program
.action(async () => {
try {
await stopContainerByName('node')
}
catch (e) {
console.log('Нет контейнера для остановки. Стартуем новый..')
}
try {
await clearDirectory(basePath)
await clearDB()
await runContainer()
+250 -304
View File
@@ -481,7 +481,7 @@ describe('тест контракта CAPITAL', () => {
expect(finalResult.creators_bonus).toBe('3820.0000 RUB')
expect(finalResult.authors_bonus).toBe('16180.0000 RUB')
expect(finalResult.generated_amount).toBe('30000.0000 RUB')
expect(finalResult.participants_bonus).toBe('48540.0000 RUB')
expect(finalResult.capitalists_bonus).toBe('48540.0000 RUB')
expect(finalResult.total_amount).toBe('78540.0000 RUB')
})
@@ -493,7 +493,7 @@ describe('тест контракта CAPITAL', () => {
expect(finalResult.creators_bonus).toBe('7640.0000 RUB')
expect(finalResult.authors_bonus).toBe('32360.0000 RUB')
expect(finalResult.generated_amount).toBe('60000.0000 RUB')
expect(finalResult.participants_bonus).toBe('97080.0000 RUB')
expect(finalResult.capitalists_bonus).toBe('97080.0000 RUB')
expect(finalResult.total_amount).toBe('157080.0000 RUB')
})
@@ -558,326 +558,272 @@ describe('тест контракта CAPITAL', () => {
})
/// ____________
// it('завершаем цикл и стартуем распределение', async () => {
// const data: CapitalContract.Actions.StartDistribution.IStart = {
// coopname: 'voskhod',
// application: 'voskhod',
// result_hash: result1.result_hash,
// }
it('завершаем цикл и стартуем распределение', async () => {
const data: CapitalContract.Actions.StartDistribution.IStart = {
coopname: 'voskhod',
application: 'voskhod',
result_hash: result1.result_hash,
}
// const result = await blockchain.api.transact(
// {
// actions: [
// {
// account: CapitalContract.contractName.production,
// name: CapitalContract.Actions.StartDistribution.actionName,
// authorization: [
// {
// actor: 'voskhod',
// permission: 'active',
// },
// ],
// data,
// },
// ],
// },
// {
// blocksBehind: 3,
// expireSeconds: 30,
// },
// )
const result = await blockchain.api.transact(
{
actions: [
{
account: CapitalContract.contractName.production,
name: CapitalContract.Actions.StartDistribution.actionName,
authorization: [
{
actor: 'voskhod',
permission: 'active',
},
],
data,
},
],
},
{
blocksBehind: 3,
expireSeconds: 30,
},
)
// getTotalRamUsage(result)
// expect(result.transaction_id).toBeDefined()
getTotalRamUsage(result)
expect(result.transaction_id).toBeDefined()
// const blockchainResult = (await blockchain.getTableRows(
// CapitalContract.contractName.production,
// 'voskhod',
// 'results',
// 1,
// result1.result_hash,
// result1.result_hash,
// 2,
// 'sha256',
// ))[0]
const blockchainResult = (await blockchain.getTableRows(
CapitalContract.contractName.production,
'voskhod',
'results',
1,
result1.result_hash,
result1.result_hash,
2,
'sha256',
))[0]
// expect(blockchainResult).toBeDefined()
// expect(blockchainResult.result_hash).toBe(result1.result_hash)
// expect(blockchainResult.project_hash).toBe(project1.project_hash)
// expect(blockchainResult.coopname).toBe('voskhod')
// expect(blockchainResult.status).toBe('started')
// })
expect(blockchainResult).toBeDefined()
expect(blockchainResult.result_hash).toBe(result1.result_hash)
expect(blockchainResult.project_hash).toBe(project1.project_hash)
expect(blockchainResult.coopname).toBe('voskhod')
expect(blockchainResult.status).toBe('opened')
})
// it('добавляем второго автора tester2', async () => {
// const data: CapitalContract.Actions.AddAuthor.IAddAuthor = {
// coopname: 'voskhod',
// application: 'voskhod',
// project_hash: project1.project_hash,
// author: tester2,
// shares: '100',
// }
it('обновляем капитал первого создателя в результате', async () => {
const data: CapitalContract.Actions.CreateClaim.ICreateClaim = {
coopname: 'voskhod',
application: 'voskhod',
result_hash: result1.result_hash,
username: tester1,
}
// const result = await blockchain.api.transact(
// {
// actions: [
// {
// account: CapitalContract.contractName.production,
// name: CapitalContract.Actions.AddAuthor.actionName,
// authorization: [
// {
// actor: 'voskhod',
// permission: 'active',
// },
// ],
// data,
// },
// ],
// },
// {
// blocksBehind: 3,
// expireSeconds: 30,
// },
// )
// getTotalRamUsage(result)
// expect(result.transaction_id).toBeDefined()
const result = await blockchain.api.transact(
{
actions: [
{
account: CapitalContract.contractName.production,
name: CapitalContract.Actions.CreateClaim.actionName,
authorization: [
{
actor: 'voskhod',
permission: 'active',
},
],
data,
},
],
},
{
blocksBehind: 3,
expireSeconds: 30,
},
)
getTotalRamUsage(result)
expect(result.transaction_id).toBeDefined()
// const project = (await blockchain.getTableRows(
// CapitalContract.contractName.production,
// 'voskhod',
// 'projects',
// 1,
// project1.project_hash,
// project1.project_hash,
// 3,
// 'sha256',
// ))[0]
const blockchainResult = (await blockchain.getTableRows(
CapitalContract.contractName.production,
'voskhod',
'results',
1,
result1.result_hash,
result1.result_hash,
2,
'sha256',
))[0]
// expect(project).toBeDefined()
// expect(project.authors_count).toBe(2)
// expect(project.authors_shares).toBe(200)
// })
expect(blockchainResult).toBeDefined()
console.log('blockchainResult: ', blockchainResult)
})
// it('добавляем коммиты создателей tester2 и tester3', async () => {
// // Добавляем второго создателя
// let data: CapitalContract.Actions.AddCreator.IAddCreator = {
// coopname: 'voskhod',
// application: 'voskhod',
// result_hash: result1.result_hash,
// creator: tester2,
// used: '100.0000 RUB',
// }
it('обновляем капитал второго создателя в результате', async () => {
const data: CapitalContract.Actions.CreateClaim.ICreateClaim = {
coopname: 'voskhod',
application: 'voskhod',
result_hash: result1.result_hash,
username: tester2,
}
// let result = await blockchain.api.transact(
// {
// actions: [
// {
// account: CapitalContract.contractName.production,
// name: CapitalContract.Actions.AddCreator.actionName,
// authorization: [
// {
// actor: 'voskhod',
// permission: 'active',
// },
// ],
// data,
// },
// ],
// },
// {
// blocksBehind: 3,
// expireSeconds: 30,
// },
// )
// getTotalRamUsage(result)
// expect(result.transaction_id).toBeDefined()
const result = await blockchain.api.transact(
{
actions: [
{
account: CapitalContract.contractName.production,
name: CapitalContract.Actions.CreateClaim.actionName,
authorization: [
{
actor: 'voskhod',
permission: 'active',
},
],
data,
},
],
},
{
blocksBehind: 3,
expireSeconds: 30,
},
)
getTotalRamUsage(result)
expect(result.transaction_id).toBeDefined()
// // Добавляем третьего создателя
// data = {
// coopname: 'voskhod',
// application: 'voskhod',
// result_hash: result1.result_hash,
// creator: tester3,
// used: '100.0000 RUB',
// }
const blockchainResult = (await blockchain.getTableRows(
CapitalContract.contractName.production,
'voskhod',
'results',
1,
result1.result_hash,
result1.result_hash,
2,
'sha256',
))[0]
// result = await blockchain.api.transact(
// {
// actions: [
// {
// account: CapitalContract.contractName.production,
// name: CapitalContract.Actions.AddCreator.actionName,
// authorization: [
// {
// actor: 'voskhod',
// permission: 'active',
// },
// ],
// data,
// },
// ],
// },
// {
// blocksBehind: 3,
// expireSeconds: 30,
// },
// )
// getTotalRamUsage(result)
// expect(result.transaction_id).toBeDefined()
expect(blockchainResult).toBeDefined()
console.log('blockchainResult: ', blockchainResult)
})
// // Проверяем финальные значения
// const blockchainResult = (await blockchain.getTableRows(
// CapitalContract.contractName.production,
// 'voskhod',
// 'results',
// 1,
// result1.result_hash,
// result1.result_hash,
// 2,
// 'sha256',
// ))[0]
it('повторно обновляем капитал второго создателя в результате и ожидаем ошибку', async () => {
const data: CapitalContract.Actions.CreateClaim.ICreateClaim = {
coopname: 'voskhod',
application: 'voskhod',
result_hash: result1.result_hash,
username: tester2,
}
// expect(blockchainResult).toBeDefined()
// expect(blockchainResult.creators_count).toBe(3)
// expect(blockchainResult.creators_amount).toBe('300.0000 RUB')
// // Ниже – пример ожидаемого роста, исходя из логики контракта
// expect(blockchainResult.creators_bonus).toBe('114.6000 RUB')
// expect(blockchainResult.authors_bonus).toBe('485.4000 RUB')
// expect(blockchainResult.generated_amount).toBe('900.0000 RUB')
// expect(blockchainResult.participants_bonus).toBe('1456.2000 RUB')
// expect(blockchainResult.total_amount).toBe('2356.2000 RUB')
// })
try {
await sleep(1000)
await blockchain.api.transact(
{
actions: [
{
account: CapitalContract.contractName.production,
name: CapitalContract.Actions.CreateClaim.actionName,
authorization: [
{
actor: 'voskhod',
permission: 'active',
},
],
data,
},
],
},
{
blocksBehind: 3,
expireSeconds: 30,
},
)
throw new Error('Ожидалась ошибка, но транзакция прошла успешно')
}
catch (error: any) {
const message = error.json?.error?.details?.[0]?.message
expect(message).toMatch(/Клайм уже существует/i)
}
})
// it('удаляем создателя tester3', async () => {
// const data: CapitalContract.Actions.DelCreator.IDelCreator = {
// coopname: 'voskhod',
// application: 'voskhod',
// result_hash: result1.result_hash,
// creator: tester3,
// }
it('обновляем капитал инвестора в результате', async () => {
const data: CapitalContract.Actions.CreateClaim.ICreateClaim = {
coopname: 'voskhod',
application: 'voskhod',
result_hash: result1.result_hash,
username: investor1,
}
// const result = await blockchain.api.transact(
// {
// actions: [
// {
// account: CapitalContract.contractName.production,
// name: CapitalContract.Actions.DelCreator.actionName,
// authorization: [
// {
// actor: 'voskhod',
// permission: 'active',
// },
// ],
// data,
// },
// ],
// },
// {
// blocksBehind: 3,
// expireSeconds: 30,
// },
// )
// getTotalRamUsage(result)
// expect(result.transaction_id).toBeDefined()
const result = await blockchain.api.transact(
{
actions: [
{
account: CapitalContract.contractName.production,
name: CapitalContract.Actions.CreateClaim.actionName,
authorization: [
{
actor: 'voskhod',
permission: 'active',
},
],
data,
},
],
},
{
blocksBehind: 3,
expireSeconds: 30,
},
)
getTotalRamUsage(result)
expect(result.transaction_id).toBeDefined()
// // Проверяем обновленные значения после удаления
// const blockchainResult = (await blockchain.getTableRows(
// CapitalContract.contractName.production,
// 'voskhod',
// 'results',
// 1,
// result1.result_hash,
// result1.result_hash,
// 2,
// 'sha256',
// ))[0]
const blockchainResult = (await blockchain.getTableRows(
CapitalContract.contractName.production,
'voskhod',
'results',
1,
result1.result_hash,
result1.result_hash,
2,
'sha256',
))[0]
// expect(blockchainResult).toBeDefined()
// expect(blockchainResult.creators_count).toBe(2)
// expect(blockchainResult.creators_amount).toBe('200.0000 RUB')
// // Уменьшаем все показатели ровно на величину последнего добавленного создателя
// expect(blockchainResult.creators_bonus).toBe('76.4000 RUB') // 114.6000 - 38.2000
// expect(blockchainResult.authors_bonus).toBe('323.6000 RUB') // 485.4000 - 161.8000
// expect(blockchainResult.generated_amount).toBe('600.0000 RUB') // 900.0000 - 300.0000
// expect(blockchainResult.participants_bonus).toBe('970.8000 RUB') // 1456.2000 - 485.4000
// expect(blockchainResult.total_amount).toBe('1570.8000 RUB') // 2356.2000 - 785.4000
// })
expect(blockchainResult).toBeDefined()
console.log('investorResult: ', blockchainResult)
})
// it('стартуем распределение долей результата', async () => {
// const data: CapitalContract.Actions.Start.IStart = {
// coopname: 'voskhod',
// application: 'voskhod',
// result_hash: result1.result_hash,
// }
it('повторно обновляем капитал инвестора в результате и ожидаем ошибку', async () => {
const data: CapitalContract.Actions.CreateClaim.ICreateClaim = {
coopname: 'voskhod',
application: 'voskhod',
result_hash: result1.result_hash,
username: investor1,
}
// const result = await blockchain.api.transact(
// {
// actions: [
// {
// account: CapitalContract.contractName.production,
// name: CapitalContract.Actions.Start.actionName,
// authorization: [
// {
// actor: 'voskhod',
// permission: 'active',
// },
// ],
// data,
// },
// ],
// },
// {
// blocksBehind: 3,
// expireSeconds: 30,
// },
// )
// getTotalRamUsage(result)
// expect(result.transaction_id).toBeDefined()
// const blockchainResult = (await blockchain.getTableRows(
// CapitalContract.contractName.production,
// 'voskhod',
// 'results',
// 1,
// result1.result_hash,
// result1.result_hash,
// 2,
// 'sha256',
// ))[0]
// expect(blockchainResult).toBeDefined()
// expect(blockchainResult.status).toBe('started')
// })
// it('пишем заявления и получаем NFT', async () => {
// const data: CapitalContract.Actions.SetStatement.ISetStatement = {
// coopname: 'voskhod',
// application: 'voskhod',
// statement: fakeDocument,
// nft_hash: generateRandomSHA256(),
// }
// const result = await blockchain.api.transact(
// {
// actions: [
// {
// account: CapitalContract.contractName.production,
// name: CapitalContract.Actions.SetStatement.actionName,
// authorization: [
// {
// actor: 'voskhod',
// permission: 'active',
// },
// ],
// data,
// },
// ],
// },
// {
// blocksBehind: 3,
// expireSeconds: 30,
// },
// )
// getTotalRamUsage(result)
// expect(result.transaction_id).toBeDefined()
// })
try {
await sleep(1000)
await blockchain.api.transact(
{
actions: [
{
account: CapitalContract.contractName.production,
name: CapitalContract.Actions.CreateClaim.actionName,
authorization: [
{
actor: 'voskhod',
permission: 'active',
},
],
data,
},
],
},
{
blocksBehind: 3,
expireSeconds: 30,
},
)
throw new Error('Ожидалась ошибка, но транзакция прошла успешно')
}
catch (error: any) {
const message = error.json?.error?.details?.[0]?.message
expect(message).toMatch(/Клайм уже существует/i)
}
})
})
@@ -50,9 +50,8 @@ export async function withdrawContribution(
username,
result_hash: resultHash,
withdraw_hash: withdrawHash,
commit_hashes: commitHashes,
contribution_statement: fakeDocument,
return_statement: fakeDocument,
amount: withdrawAmount,
}
console.log(`\n🚀 Отправка транзакции CreateWithdraw для ${username} на сумму ${withdrawAmount}`)
@@ -79,7 +78,7 @@ export async function withdrawContribution(
let blockchainWithdraw = (await blockchain.getTableRows(
CapitalContract.contractName.production,
coopname,
'withdraws',
CapitalContract.Tables.ResultWithdraws.tableName,
1,
withdrawHash,
withdrawHash,
@@ -98,7 +97,6 @@ export async function withdrawContribution(
application: coopname,
approver: 'ant',
withdraw_hash: withdrawHash,
approved_contribution_statement: fakeDocument,
approved_return_statement: fakeDocument,
}
@@ -126,7 +124,7 @@ export async function withdrawContribution(
blockchainWithdraw = (await blockchain.getTableRows(
CapitalContract.contractName.production,
coopname,
'withdraws',
CapitalContract.Tables.ResultWithdraws.tableName,
1,
withdrawHash,
withdrawHash,
@@ -146,17 +144,15 @@ export async function withdrawContribution(
1000,
)
const lastDecision = decisions[decisions.length - 1]
const prevLastDecision = decisions[decisions.length - 2]
console.log(`\n📜 Выполнение решений: ${prevLastDecision.id}, ${lastDecision.id}`)
console.log(`\n📜 Выполнение решения: ${lastDecision.id}`)
await processDecision(blockchain, prevLastDecision.id)
await processDecision(blockchain, lastDecision.id)
blockchainWithdraw = (await blockchain.getTableRows(
CapitalContract.contractName.production,
coopname,
'withdraws',
CapitalContract.Tables.ResultWithdraws.tableName,
1,
withdrawHash,
withdrawHash,
@@ -203,7 +199,9 @@ export async function withdrawContribution(
expect(parseFloat(programWallet.blocked)).toBe(parseFloat(prevProgramWallet.blocked))
// Проверка изменения spend в проекте
expect(parseFloat(finalProject.spend)).toBe(parseFloat(prevProject.spend) + parseFloat(withdrawAmount))
expect(parseFloat(finalProject.withdrawed)).toBe(parseFloat(prevProject.withdrawed) + parseFloat(withdrawAmount))
expect(parseFloat(finalProject.spend)).toBe(parseFloat(prevProject.spend))
console.log(`\n✅ Возврат на ${withdrawAmount} завершен успешно!`)
+34 -21
View File
@@ -9,7 +9,7 @@
#include "src/investment/capauthinvst.cpp"
#include "src/claim/approveclaim.cpp"
#include "src/claim/updatecapitl.cpp"
#include "src/claim/createclaim.cpp"
#include "src/claim/claimnow.cpp"
#include "src/claim/capauthclaim.cpp"
@@ -32,9 +32,7 @@
#include "src/withdraw_from_result/createwthd1.cpp"
#include "src/withdraw_from_result/capauthwthdc.cpp"
#include "src/withdraw_from_result/capauthwthdr.cpp"
#include "src/withdraw_from_result/authwithdrw1.cpp"
#include "src/withdraw_from_result/capauthwthd1.cpp"
#include "src/withdraw_from_result/approvewthd1.cpp"
#include "src/withdraw_from_project/createwthd2.cpp"
@@ -45,6 +43,8 @@
#include "src/withdraw_from_program/capauthwthd3.cpp"
#include "src/withdraw_from_program/approvewthd3.cpp"
#include "src/convert/approvecnvrt.cpp"
#include "src/convert/createcnvrt.cpp"
#include "src/expense/approveexpns.cpp"
#include "src/expense/capauthexpns.cpp"
@@ -198,11 +198,11 @@ std::optional<contributor> capital::get_active_contributor_or_fail(eosio::name c
}
std::optional<capital_tables::participant> capital::get_participant(eosio::name coopname, eosio::name username) {
capital_tables::participant_index participants(_capital, coopname.value);
std::optional<capital_tables::capitalist> capital::get_capitalist(eosio::name coopname, eosio::name username) {
capital_tables::capitalist_index capitalists(_capital, coopname.value);
auto itr = participants.find(username.value);
if (itr == participants.end()) {
auto itr = capitalists.find(username.value);
if (itr == capitalists.end()) {
return std::nullopt;
}
@@ -386,21 +386,34 @@ std::optional<capital_tables::project_withdraw> capital::get_project_withdraw(eo
}
std::optional<claim> capital::get_claim(eosio::name coopname, const checksum256 &claim_hash) {
std::optional<claim> capital::get_claim(eosio::name coopname, const checksum256 &result_hash, eosio::name username) {
claim_index claims(_capital, coopname.value);
auto claim_hash_index = claims.get_index<"byhash"_n>();
auto idx = claims.get_index<"byresuser"_n>();
auto rkey = combine_checksum_ids(result_hash, username);
auto claim_itr = claim_hash_index.find(claim_hash);
auto it = idx.find(rkey);
if (it == idx.end()) {
return std::nullopt;
}
return *it;
}
if (claim_itr == claim_hash_index.end()) {
std::optional<convert> capital::get_convert(eosio::name coopname, const checksum256 &hash) {
convert_index converts(_capital, coopname.value);
auto index = converts.get_index<"byhash"_n>();
auto itr = index.find(hash);
if (itr == index.end()) {
return std::nullopt;
}
return *claim_itr;
return *itr;
}
claim capital::get_claim_or_fail(eosio::name coopname, const checksum256 &claim_hash, const char* msg) {
auto c = get_claim(coopname, claim_hash);
claim capital::get_claim_or_fail(eosio::name coopname, const checksum256 &result_hash, eosio::name username, const char* msg) {
auto c = get_claim(coopname, result_hash, username);
eosio::check(c.has_value(), msg);
return *c;
}
@@ -464,8 +477,8 @@ void capital::ensure_contributor(name coopname, name username) {
// - creators_bonus = spend * 0.382
// - authors_bonus = spend * 1.618
// - generated = spend + creators_bonus + authors_bonus
// - participants_bonus = generated * 1.618
// - total = generated + participants_bonus
// - capitalists_bonus = generated * 1.618
// - total = generated + capitalists_bonus
//----------------------------------------------------------------------------
bonus_result capital::calculcate_capital_amounts(int64_t spend_amount) {
bonus_result br{};
@@ -482,11 +495,11 @@ bonus_result capital::calculcate_capital_amounts(int64_t spend_amount) {
// 3) generated = spend + creators_bonus + authors_bonus
br.generated = int64_t(spend + br.creators_bonus + br.authors_bonus);
// 4) participants_bonus = generated * 1.618
br.participants_bonus = int64_t(double(br.generated) * 1.618);
// 4) capitalists_bonus = generated * 1.618
br.capitalists_bonus = int64_t(double(br.generated) * 1.618);
// 5) total = generated + participants_bonus
br.total = int64_t(br.generated + br.participants_bonus);
// 5) total = generated + capitalists_bonus
br.total = int64_t(br.generated + br.capitalists_bonus);
return br;
}
+31 -28
View File
@@ -35,16 +35,10 @@ public:
//Возврат из результата
[[eosio::action]]
void createwthd1(eosio::name coopname, eosio::name application, eosio::name username, checksum256 result_hash, checksum256 withdraw_hash, std::vector<checksum256> commit_hashes, document contribution_statement, document return_statement);
void createwthd1(eosio::name coopname, eosio::name application, eosio::name username, checksum256 result_hash, checksum256 withdraw_hash, asset amount, document return_statement);
[[eosio::action]]
void capauthwthdc(eosio::name coopname, uint64_t withdraw_id, document authorization);
[[eosio::action]]
void capauthwthdr(eosio::name coopname, uint64_t withdraw_id, document authorization);
[[eosio::action]]
void authwithdrw1(eosio::name coopname, checksum256 withdraw_hash);
void capauthwthd1(eosio::name coopname, uint64_t withdraw_id, document authorization);
// Возврат из проекта
[[eosio::action]]
@@ -82,7 +76,12 @@ public:
// claims
[[eosio::action]]
void updatecapitl(name coopname, name application, name username, checksum256 result_hash, checksum256 claim_hash);
void createclaim(
eosio::name coopname,
eosio::name application,
eosio::name username,
checksum256 result_hash
);
[[eosio::action]]
void claimnow(name coopname, name application, name username, checksum256 result_hash, document statement);
@@ -91,7 +90,21 @@ public:
void capauthclaim(eosio::name coopname, uint64_t claim_id, document decision);
[[eosio::action]]
void approveclaim(eosio::name coopname, eosio::name application, eosio::name approver, checksum256 claim_hash, document approved_statement);
void approveclaim(eosio::name coopname, eosio::name application, eosio::name approver, eosio::name username, checksum256 result_hash, document approved_statement);
// конвертация
[[eosio::action]]
void approvecnvrt(eosio::name coopname, eosio::name application, eosio::name approver, checksum256 convert_hash, document approved_statement);
[[eosio::action]]
void createcnvrt(
eosio::name coopname,
eosio::name application,
eosio::name username,
checksum256 result_hash,
checksum256 convert_hash,
document convert_statement
);
[[eosio::action]]
void startdistrbn(name coopname, name application, checksum256 result_hash);
@@ -136,8 +149,8 @@ public:
void diallocate(eosio::name coopname, eosio::name application, checksum256 project_hash, checksum256 result_hash, eosio::asset amount);
[[eosio::action]]
void approvewthd1(name coopname, name application, name approver, checksum256 withdraw_hash, document approved_contribution_statement, document approved_return_statement);
void approvewthd1(name coopname, name application, name approver, checksum256 withdraw_hash, document approved_return_statement);
// Расходы
[[eosio::action]]
void createexpnse(eosio::name coopname, eosio::name application, checksum256 expense_hash, checksum256 result_hash, name creator, uint64_t fund_id, asset amount, std::string description, document statement);
@@ -186,6 +199,7 @@ private:
std::optional<author> get_author(eosio::name coopname, eosio::name username, const checksum256 &project_hash);
std::optional<creator> get_creator(eosio::name coopname, eosio::name username, const checksum256 &result_hash);
std::optional<result> get_result(eosio::name coopname, const checksum256 &result_hash);
std::optional<project> get_project(eosio::name coopname, const checksum256 &project_hash);
std::optional<project> get_master_project(eosio::name coopname);
void validate_project_hierarchy_depth(eosio::name coopname, checksum256 project_hash);
@@ -194,7 +208,9 @@ private:
int64_t get_capital_user_share_balance(eosio::name coopname, eosio::name username);
std::optional<claim> get_claim(eosio::name coopname, const checksum256 &result_hash);
std::optional<claim> get_claim(eosio::name coopname, const checksum256 &result_hash, eosio::name username);
std::optional<convert> get_convert(eosio::name coopname, const checksum256 &hash);
std::optional<result_author> get_result_author(eosio::name coopname, eosio::name username, const checksum256 &result_hash);
std::optional<commit> get_commit(eosio::name coopname, const checksum256 &hash);
std::optional<invest> get_invest(eosio::name coopname, const checksum256 &invest_hash);
@@ -211,7 +227,7 @@ private:
std::optional<contributor> get_contributor(eosio::name coopname, const checksum256 &project_hash, eosio::name username);
std::optional<contributor> get_active_contributor_or_fail(eosio::name coopname, const checksum256 &project_hash, eosio::name username);
std::optional<capital_tables::participant> get_participant(eosio::name coopname, eosio::name username);
std::optional<capital_tables::capitalist> get_capitalist(eosio::name coopname, eosio::name username);
int64_t get_capital_program_share_balance(eosio::name coopname);
@@ -225,20 +241,7 @@ private:
resactor get_resactor_or_fail(eosio::name coopname, const checksum256 &result_hash, eosio::name username, const char* msg);
std::optional<resactor> get_resactor(eosio::name coopname, const checksum256 &result_hash, eosio::name username);
claim get_claim_or_fail(eosio::name coopname, const checksum256 &claim_hash, const char* msg);
claim get_claim_or_fail(eosio::name coopname, const checksum256 &result_hash, eosio::name username, const char* msg);
result get_result_or_fail(eosio::name coopname, const checksum256 &result_hash, const char* msg);
void try_finalize_withdrawal(eosio::name coopname, const capital_tables::result_withdraws_index::const_iterator &withdraw) {
if (!is_document_empty(withdraw->authorized_return_statement) &&
!is_document_empty(withdraw->authorized_contribution_statement)) {
action(
permission_level{_capital, "active"_n},
_capital,
"authwithdrw1"_n,
std::make_tuple(coopname, withdraw->withdraw_hash)
).send();
}
}
};
@@ -9,31 +9,35 @@ struct bonus_result {
int64_t creators_bonus;
int64_t authors_bonus;
int64_t generated;
int64_t participants_bonus;
int64_t capitalists_bonus;
int64_t total;
};
// resactors.hpp (или в capital.hpp)
struct [[eosio::table, eosio::contract(CAPITAL)]] resactor {
uint64_t id;
checksum256 project_hash; // С каким результатом связана запись
checksum256 result_hash; // С каким результатом связана запись
eosio::name username; // Чей это учёт
eosio::asset available = asset(0, _root_govern_symbol);
eosio::asset for_convert = asset(0, _root_govern_symbol);
eosio::asset spend = asset(0, _root_govern_symbol);
// Сколько пользователь имеет «авторских долей» в этом результате
uint64_t authors_shares = 0;
int64_t reward_per_share_last_authors = 0;
// Сколько пользователь имеет «создательских долей» (для creators_bonus)
// (available + for_convert) на момент фиксации
uint64_t creators_shares = 0;
int64_t reward_per_share_last_creators = 0;
// Сколько пользователь имеет «пайщических долей» (participants)
uint64_t participants_shares = 0;
int64_t reward_per_share_last_participants = 0;
// Сколько пользователь имеет «создательских долей» в creators_bonus
uint64_t creators_bonus_shares = 0;
// Сколько часов вложено в результат
uint64_t contributed_hours = 0;
uint64_t primary_key() const { return id; }
checksum256 by_result_hash() const { return result_hash; } ///< Индекс по хэшу результата
checksum256 by_project_hash() const { return project_hash; } ///< Индекс по хэшу проекта
// Индекс по (result_hash + username)
uint128_t by_resuser() const {
return combine_checksum_ids(result_hash, username);
@@ -42,6 +46,8 @@ struct [[eosio::table, eosio::contract(CAPITAL)]] resactor {
typedef eosio::multi_index<
"resactors"_n, resactor,
indexed_by<"byproject"_n, const_mem_fun<resactor, checksum256, &resactor::by_project_hash>>,
indexed_by<"byresult"_n, const_mem_fun<resactor, checksum256, &resactor::by_result_hash>>,
indexed_by<"byresuser"_n, const_mem_fun<resactor, uint128_t, &resactor::by_resuser>>
> resactor_index;
@@ -172,22 +178,21 @@ struct [[eosio::table, eosio::contract(CAPITAL)]] contributor {
eosio::asset invested = asset(0, _root_govern_symbol);
uint64_t contributed_hours;
eosio::asset rate_per_hour;
eosio::asset spend = asset(0, _root_govern_symbol);
uint64_t convert_percent;
eosio::asset for_convert = asset(0, _root_govern_symbol);
uint64_t contributed_hours;
eosio::asset available = asset(0, _root_govern_symbol);
eosio::asset rate_per_hour = asset(0, _root_govern_symbol);
eosio::asset spend = asset(0, _root_govern_symbol);
eosio::asset withdrawed = asset(0, _root_govern_symbol);
eosio::asset converted = asset(0, _root_govern_symbol);
eosio::asset expensed = asset(0, _root_govern_symbol);
eosio::asset returned = asset(0, _root_govern_symbol);
eosio::asset claimed = asset(0, _root_govern_symbol);
eosio::asset share_balance = asset(0, _root_govern_symbol); ///< Баланс долей вкладчика
eosio::asset share_balance = asset(0, _root_govern_symbol); ///< Баланс долей пайщика
eosio::asset pending_rewards = asset(0, _root_govern_symbol); ///< Накопленные награды
int64_t reward_per_share_last = 0; ///< Последний зафиксированный cumulative_reward_per_share
int64_t reward_per_share_last = 0; ///< Последний зафиксированный cumulative_reward_per_share по проекту
uint64_t primary_key() const { return id; }
uint64_t by_username() const { return username.value; }
@@ -232,11 +237,13 @@ struct [[eosio::table, eosio::contract(CAPITAL)]] project {
eosio::asset spend = asset(0, _root_govern_symbol);
eosio::asset generated = asset(0, _root_govern_symbol);
eosio::asset converted = asset(0, _root_govern_symbol);
eosio::asset claimed = asset(0, _root_govern_symbol);
eosio::asset withdrawed = asset(0, _root_govern_symbol);
double parent_distribution_ratio = 1;
int64_t membership_cumulative_reward_per_share = 0;
eosio::asset membership_total_shares = asset(0, _root_govern_symbol); ///< Общее количество долей пайщиков в проекте
eosio::asset total_share_balance = asset(0, _root_govern_symbol); ///< Общее количество долей пайщиков в проекте
eosio::asset membership_funded = asset(0, _root_govern_symbol); ///< Общее количество поступивших членских взносов
eosio::asset membership_available = asset(0, _root_govern_symbol); ///< Доступное количество членских взносов для участников проекта согласно долям
eosio::asset membership_distributed = asset(0, _root_govern_symbol); ///< Распределенное количество членских взносов на участников проекта
@@ -264,28 +271,34 @@ struct [[eosio::table, eosio::contract(CAPITAL)]] result {
time_point_sec created_at = current_time_point();
time_point_sec expired_at = eosio::time_point_sec(eosio::current_time_point().sec_since_epoch() + 365 * 86400);
uint64_t authors_shares;
uint64_t authors_count;
uint64_t total_creators_bonus_shares;
uint64_t authors_count;
uint64_t commits_count;
eosio::asset allocated = asset(0, _root_govern_symbol); ///< аллоцированные на создание результата средства
eosio::asset available = asset(0, _root_govern_symbol); ///< зарезерированные на создание результата средства
eosio::asset spend = asset(0, _root_govern_symbol); ///< фактически потраченные ресурсы на создание результат в виде времени (паевые взносы-возвраты)
eosio::asset expensed = asset(0, _root_govern_symbol); ///< фактически потраченные на создание результата средства в виде расходов (подписки, прочее)
eosio::asset withdrawed = asset(0, _root_govern_symbol); ///< фактически возвращенные средства из результата
eosio::asset creators_amount = asset(0, _root_govern_symbol); ///< себестоимость РИД
eosio::asset generated_amount = asset(0, _root_govern_symbol); ///< стоимость РИД с учётом премий авторов и создателей
eosio::asset creators_bonus = asset(0, _root_govern_symbol); ///< премии создателей - 0.382 от себестоимости (creators_amount)
eosio::asset authors_bonus = asset(0, _root_govern_symbol); ///< премии авторов - 1.618 от себестоимости (creators_amount)
eosio::asset generated_amount = asset(0, _root_govern_symbol); ///< стоимость РИД с учётом премий авторов и создателей
eosio::asset participants_bonus = asset(0, _root_govern_symbol); ///< премии пайщиков кооператива - 1.618 от generated_amount
eosio::asset capitalists_bonus = asset(0, _root_govern_symbol); ///< премии пайщиков кооператива - 1.618 от generated_amount
eosio::asset total_amount = asset(0, _root_govern_symbol); ///< Капитализация РИД (стоимость РИД в generated_amount + participants_bonus)
eosio::asset participants_bonus_remain = asset(0, _root_govern_symbol); ///< сумма остатка для выплаты пайщикам
eosio::asset total_amount = asset(0, _root_govern_symbol); ///< Капитализация РИД (стоимость РИД в generated_amount + capitalists_bonus)
eosio::asset authors_bonus_remain = asset(0, _root_govern_symbol); ///< сумма остатка для выплаты авторам
eosio::asset creators_amount_remain = asset(0, _root_govern_symbol); ///< сумма остатка для выплаты авторам
eosio::asset creators_bonus_remain = asset(0, _root_govern_symbol); ///< сумма остатка для выплаты авторам
eosio::asset capitalists_bonus_remain = asset(0, _root_govern_symbol); ///< сумма остатка для выплаты пайщикам
int64_t authors_cumulative_reward_per_share = 0; // CRPS для авторов
int64_t creators_cumulative_reward_per_share = 0; // CRPS для создателей
int64_t participants_cumulative_reward_per_share = 0; // CRPS для пайщиков
uint64_t primary_key() const { return id; } ///< Основной ключ.
checksum256 by_hash() const { return result_hash; } ///< Индекс по хэшу результата.
checksum256 by_project_hash() const { return project_hash; } ///< Индекс по хэшу идеи
@@ -300,7 +313,6 @@ struct [[eosio::table, eosio::contract(CAPITAL)]] result {
struct [[eosio::table, eosio::contract(CAPITAL)]] claim {
uint64_t id;
checksum256 claim_hash;
checksum256 project_hash;
checksum256 result_hash;
@@ -311,17 +323,20 @@ struct [[eosio::table, eosio::contract(CAPITAL)]] claim {
eosio::name status = "created"_n; ///< created | statement | decision | act1 | act2 | completed
time_point_sec created_at = current_time_point();
eosio::asset amount = asset(0, _root_govern_symbol);
eosio::asset author_amount = asset(0, _root_govern_symbol);
eosio::asset creator_amount = asset(0, _root_govern_symbol);
eosio::asset capitalist_amount = asset(0, _root_govern_symbol);
eosio::asset total_amount = asset(0, _root_govern_symbol);
document claim_statement; ///< Заявление
document approved_statement; ///< Принятое заявление
document authorization; ///< Решение
uint64_t primary_key() const { return id; } ///< Основной ключ.
uint64_t by_username() const { return username.value; } ///< Индекс по владельцу
checksum256 by_hash() const { return claim_hash; } ///< Индекс по хэшу
checksum256 by_result_hash() const { return result_hash; } ///< Индекс по хэшу
checksum256 by_project_hash() const { return project_hash; } ///< Индекс по хэшу идеи
checksum256 by_project_hash() const { return project_hash; } ///< Индекс по хэшу проекта
uint128_t by_result_user() const {
return combine_checksum_ids(result_hash, username);
@@ -330,13 +345,49 @@ struct [[eosio::table, eosio::contract(CAPITAL)]] claim {
typedef eosio::multi_index<"claims"_n, claim,
indexed_by<"byusername"_n, const_mem_fun<claim, uint64_t, &claim::by_username>>,
indexed_by<"byhash"_n, const_mem_fun<claim, checksum256, &claim::by_hash>>,
indexed_by<"byresulthash"_n, const_mem_fun<claim, checksum256, &claim::by_result_hash>>,
indexed_by<"byresult"_n, const_mem_fun<claim, checksum256, &claim::by_result_hash>>,
indexed_by<"byprojecthash"_n, const_mem_fun<claim, checksum256, &claim::by_project_hash>>,
indexed_by<"byresuser"_n, const_mem_fun<claim, uint128_t, &claim::by_result_user>>
> claim_index;
struct [[eosio::table, eosio::contract(CAPITAL)]] convert {
uint64_t id;
checksum256 project_hash;
checksum256 result_hash;
checksum256 convert_hash;
eosio::name coopname;
eosio::name username;
eosio::name status = "created"_n; ///< created
eosio::asset convert_amount = asset(0, _root_govern_symbol);
document convert_statement; ///< Заявление
time_point_sec created_at = current_time_point();
uint64_t primary_key() const { return id; } ///< Основной ключ.
uint64_t by_username() const { return username.value; } ///< Индекс по владельцу
checksum256 by_convert_hash() const { return convert_hash; } ///< Индекс по хэшу
checksum256 by_result_hash() const { return result_hash; } ///< Индекс по хэшу
checksum256 by_project_hash() const { return project_hash; } ///< Индекс по хэшу проекта
uint128_t by_result_user() const {
return combine_checksum_ids(result_hash, username);
}
};
typedef eosio::multi_index<"converts"_n, convert,
indexed_by<"byusername"_n, const_mem_fun<convert, uint64_t, &convert::by_username>>,
indexed_by<"byhash"_n, const_mem_fun<convert, checksum256, &convert::by_convert_hash>>,
indexed_by<"byresult"_n, const_mem_fun<convert, checksum256, &convert::by_result_hash>>,
indexed_by<"byprojecthash"_n, const_mem_fun<convert, checksum256, &convert::by_project_hash>>
> convert_index;
struct [[eosio::table, eosio::contract(CAPITAL)]] author {
uint64_t id;
checksum256 project_hash;
@@ -445,7 +496,7 @@ struct [[eosio::table, eosio::contract(CAPITAL)]] global_state {
namespace capital_tables {
struct [[eosio::table, eosio::contract(CAPITAL)]] participant {
struct [[eosio::table, eosio::contract(CAPITAL)]] capitalist {
name username; ///< Имя пользователя
name coopname; ///< Имя кооператива
asset pending_rewards = asset(0, _root_govern_symbol); ///< Вознаграждения ожидающие получения
@@ -455,7 +506,7 @@ namespace capital_tables {
uint64_t primary_key() const { return username.value; } ///< Основной ключ.
};
typedef eosio::multi_index<"participants"_n, participant> participant_index; ///< Таблица для хранения участников программы капитализации
typedef eosio::multi_index<"capitalists"_n, capitalist> capitalist_index; ///< Таблица для хранения участников программы капитализации
struct [[eosio::table, eosio::contract(CAPITAL)]] result_withdraw {
@@ -466,7 +517,6 @@ namespace capital_tables {
checksum256 withdraw_hash; ///< Уникальный внешний ключ
name username; ///< Имя аккаунта участника, запрашивающего возврат.
name status = "created"_n; ///< Статус взноса-возврата (created | approved | )
std::vector<checksum256> commit_hashes; ///< Погашаемые коммиты
asset amount = asset(0, _root_govern_symbol); ///< Запрошенная сумма для возврата.
document contribution_statement; ///< Заявление на паевой взнос авторскими правами
document return_statement; ///< Заявление на возврат паевого взноса деньгами
@@ -1,16 +1,14 @@
void capital::approveclaim(eosio::name coopname, eosio::name application, eosio::name approver, checksum256 claim_hash, document approved_statement){
void capital::approveclaim(eosio::name coopname, eosio::name application, eosio::name approver, eosio::name username, checksum256 result_hash, document approved_statement){
check_auth_or_fail(_capital, coopname, application, "approveclaim"_n);
verify_document_or_fail(approved_statement);
auto exist_claim = get_claim(coopname, claim_hash);
eosio::check(exist_claim.has_value(), "Действие с указанным хэшем не существует");
auto exist_claim = get_claim(coopname, result_hash, username);
eosio::check(exist_claim.has_value(), "Клайм пользователя для результата не существует");
auto result = get_result(coopname, exist_claim -> result_hash);
auto result = get_result(coopname, result_hash);
eosio::check(result.has_value(), "Результат не найден");
eosio::check(result -> status == "created"_n, "Нельзя добавить действие в уже закрытый результат");
claim_index claims(_capital, coopname.value);
auto claim = claims.find(exist_claim -> id);
@@ -20,21 +20,20 @@ void capital::capauthclaim(eosio::name coopname, uint64_t claim_id, document dec
auto contributor_for_modify = contributors.find(contributor -> id);
contributors.modify(contributor_for_modify, coopname, [&](auto &c){
c.converted += claim -> amount;
c.claimed += claim -> total_amount;
c.share_balance += claim -> total_amount;
});
projects.modify(project, coopname, [&](auto &p) {
p.converted += claim -> amount;
p.claimed += claim -> total_amount;
p.total_share_balance += claim -> total_amount;
});
//Удаляем объект claim за ненадобностью
claims.erase(claim);
std::string memo = "Зачёт части целевого паевого взноса по договору УХД с ID: " + std::to_string(contributor -> id) + " в качестве паевого взноса по программе 'Цифровой Кошелёк' с ID: " + std::to_string(claim_id);
//Списываем баланс средств с УХД
Wallet::add_blocked_funds(_capital, coopname, claim -> username, claim -> amount, _source_program, memo);
//Увеличиваем баланс средств в капитализации
Wallet::add_blocked_funds(_capital, coopname, claim -> username, claim -> amount, _capital_program, memo);
Wallet::add_blocked_funds(_capital, coopname, claim -> username, claim -> total_amount, _capital_program, memo);
//Удаляем объект claim за ненадобностью
claims.erase(claim);
};
@@ -1,11 +1,11 @@
void capital::claimnow(name coopname, name application, name username, checksum256 claim_hash, document statement) {
void capital::claimnow(name coopname, name application, name username, checksum256 result_hash, document statement) {
check_auth_or_fail(_capital, coopname, application, "claimnow"_n);
// проверяем заявление
verify_document_or_fail(statement);
// извлекаем клайм
auto claim = get_claim(coopname, claim_hash);
auto claim = get_claim(coopname, result_hash, username);
eosio::check(claim.has_value(), "Объект запроса доли не найден");
eosio::check(claim->status == "pending"_n, "Нельзя изменить статус клайма");
eosio::check(claim -> username == username, "Неверно указано имя пользователя владельца результата");
@@ -0,0 +1,131 @@
void capital::createclaim(
eosio::name coopname,
eosio::name application,
eosio::name username,
checksum256 result_hash
) {
// Авторизация
check_auth_or_fail(_capital, coopname, application, "createclaim"_n);
// Получаем результат (или кидаем ошибку)
auto exist_result = get_result_or_fail(coopname, result_hash, "Результат не найден");
eosio::check(exist_result.status == "opened"_n, "Распределение стоимости результата еще не начато или уже завершено");
// Проверяем, нет ли уже такого клайма
auto existing_claim = get_claim(coopname, result_hash, username);
eosio::check(!existing_claim.has_value(), "Клайм уже существует");
// Находим запись в таблице results
result_index results(_capital, coopname.value);
auto result = results.find(exist_result.id);
// Получаем контрибьютора
auto exist_contributor = get_active_contributor_or_fail(coopname, exist_result.project_hash, username);
contributor_index contributors(_capital, coopname.value);
auto contributor = contributors.find(exist_contributor->id);
// Попробуем найти resactor
auto optional_resactor = get_resactor(coopname, result_hash, username);
//=== (A) Авторская часть ===
uint64_t author_amount = 0;
{
// Если resactor есть, считаем долю.
if (optional_resactor.has_value()) {
auto resactor = *optional_resactor;
// Исходная сумма (просто authors_bonus.amount)
uint64_t authors_total = result -> authors_bonus.amount;
// Доля пользователя
uint64_t user_auth_shares = resactor.authors_shares;
// Всего долей авторов
uint64_t total_auth_shares = result -> authors_shares;
if (authors_total > 0 && total_auth_shares > 0 && user_auth_shares > 0) {
uint128_t tmp = (uint128_t)authors_total * (uint128_t)user_auth_shares;
author_amount = (uint64_t)(tmp / (uint128_t)total_auth_shares);
print(result->authors_bonus_remain.amount, ", ", author_amount);
eosio::check(result->authors_bonus_remain.amount >= author_amount,
"Недостаточно средств для авторов");
}
}
}
//=== (B) Создательская часть бонусов ===
uint64_t creator_amount = 0;
{
if (optional_resactor.has_value()) {
auto resactor = *optional_resactor;
uint64_t creators_bonus_total = result->creators_bonus.amount; // вся сумма создателей
uint64_t user_creator_bonus_shares = resactor.creators_bonus_shares;
uint64_t total_creators_bonus_shares= result->total_creators_bonus_shares;
if (creators_bonus_total > 0 && total_creators_bonus_shares > 0 && user_creator_bonus_shares > 0) {
uint128_t tmp = (uint128_t)creators_bonus_total * (uint128_t)user_creator_bonus_shares;
creator_amount = (uint64_t)(tmp / (uint128_t)total_creators_bonus_shares);
eosio::check(result->creators_bonus_remain.amount >= creator_amount, "Недостаточно средств для создателей");
}
}
}
//=== (C) Капиталисты ===
// здесь resactor НЕ обязателен, доли берём из глобальных методов
uint64_t capitalist_amount = 0;
{
// Полная сумма для капиталистов
uint64_t capitals_total = result->capitalists_bonus.amount;
// Пользовательские доли берем из кошелька программы
uint64_t user_cap_shares = get_capital_user_share_balance(coopname, username);
// Общее число долей капиталистов во всей программе
uint64_t total_cap_shares = get_capital_program_share_balance(coopname);
if (capitals_total > 0 && total_cap_shares > 0 && user_cap_shares > 0) {
uint128_t tmp = (uint128_t)capitals_total * (uint128_t)user_cap_shares;
capitalist_amount = (uint64_t)(tmp / (uint128_t)total_cap_shares);
eosio::check(result->capitalists_bonus_remain.amount >= capitalist_amount,
"Недостаточно средств для пайщиков");
}
}
//=== Складываем всё ===
uint64_t total_claim_amount = author_amount + creator_amount + capitalist_amount;
eosio::asset total_amount(total_claim_amount, _root_govern_symbol);
//=== Создаём запись в claims ===
claim_index claims(_capital, coopname.value);
uint64_t claim_id = get_global_id_in_scope(_capital, coopname, "claims"_n);
claims.emplace(coopname, [&](auto &n) {
n.id = claim_id;
n.username = username;
n.result_hash = result_hash;
n.coopname = coopname;
n.status = "created"_n;
n.author_amount = asset(author_amount, _root_govern_symbol);
n.creator_amount = asset(creator_amount, _root_govern_symbol);
n.capitalist_amount = asset(capitalist_amount, _root_govern_symbol);
n.total_amount = total_amount;
});
//=== Уменьшаем остаток bonus_remain ===
results.modify(result, coopname, [&](auto &r){
// авторы
if (author_amount > 0) {
r.authors_bonus_remain -= eosio::asset(author_amount, _root_govern_symbol);
}
// создатели
if (creator_amount > 0) {
r.creators_bonus_remain -= eosio::asset(creator_amount, _root_govern_symbol);
}
// капиталисты
if (capitalist_amount > 0) {
r.capitalists_bonus_remain -= eosio::asset(capitalist_amount, _root_govern_symbol);
}
});
}
@@ -1,133 +0,0 @@
void capital::updatecapitl(
eosio::name coopname,
eosio::name application,
eosio::name username,
checksum256 result_hash,
checksum256 claim_hash
) {
// Авторизация
check_auth_or_fail(_capital, coopname, application, "updatecapitl"_n);
// Проверяем программу и кошелёк
auto capital_program = get_capital_program_or_fail(coopname);
auto capital_wallet = get_capital_wallet(coopname, username);
eosio::check(!capital_wallet.has_value(), "Нет соглашения целевой программы!");
// Проверяем, нет ли уже такого клайма
auto existing_claim = get_claim(coopname, claim_hash);
eosio::check(!existing_claim.has_value(), "Клайм уже существует");
// Получаем результат (или кидаем ошибку)
auto res_obj = get_result_or_fail(coopname, result_hash, "Результат не найден");
// Получаем запись resactor ИЛИ кидаем ошибку
auto user_resactor = get_resactor_or_fail(
coopname,
result_hash,
username,
"Пользователь не имеет долей (resactor) в данном результате, сначала зарегистрируйтесь"
);
// Находим запись в таблице results, чтобы получить CRPS и participants_bonus_remain
result_index results(_capital, coopname.value);
auto res_itr = results.find(res_obj.id);
eosio::check(res_itr != results.end(), "Результат не найден в multi_index results");
// 1) Считаем начисление по трём категориям
uint64_t author_amount = 0;
uint64_t creator_bonus_amount= 0;
uint64_t participant_amount = 0;
// Авторы
if (user_resactor.authors_shares > 0) {
int64_t current_crps_auth = res_itr->authors_cumulative_reward_per_share;
int64_t last_crps_auth = user_resactor.reward_per_share_last_authors;
int64_t delta_auth = current_crps_auth - last_crps_auth;
if (delta_auth > 0) {
author_amount = static_cast<uint64_t>(
(static_cast<uint128_t>(user_resactor.authors_shares) *
static_cast<uint128_t>(delta_auth)) / REWARD_SCALE
);
}
}
// Создатели
if (user_resactor.creators_shares > 0) {
int64_t current_crps_creat = res_itr->creators_cumulative_reward_per_share;
int64_t last_crps_creat = user_resactor.reward_per_share_last_creators;
int64_t delta_creat = current_crps_creat - last_crps_creat;
if (delta_creat > 0) {
creator_bonus_amount = static_cast<uint64_t>(
(static_cast<uint128_t>(user_resactor.creators_shares) *
static_cast<uint128_t>(delta_creat)) / REWARD_SCALE
);
}
}
// Пайщики
if (user_resactor.participants_shares > 0) {
int64_t current_crps_parts = res_itr->participants_cumulative_reward_per_share;
int64_t last_crps_parts = user_resactor.reward_per_share_last_participants;
int64_t delta_parts = current_crps_parts - last_crps_parts;
if (delta_parts > 0) {
participant_amount = static_cast<uint64_t>(
(static_cast<uint128_t>(user_resactor.participants_shares) *
static_cast<uint128_t>(delta_parts)) / REWARD_SCALE
);
}
}
// 2) Складываем всё
uint64_t total_claim_amount = author_amount + creator_bonus_amount + participant_amount;
eosio::asset amount(total_claim_amount, _root_govern_symbol);
// 3) Создаём запись в таблице claims
claim_index claims(_capital, coopname.value);
uint64_t claim_id = get_global_id_in_scope(_capital, coopname, "claims"_n);
claims.emplace(coopname, [&](auto &n) {
n.id = claim_id;
n.claim_hash = claim_hash;
n.username = username;
n.result_hash= result_hash;
n.coopname = coopname;
n.status = "created"_n;
n.amount = amount;
});
// 4) Уменьшаем participants_bonus_remain (если надо)
eosio::check(res_itr->participants_bonus_remain.amount >= participant_amount, "Недостаточно средств для пайщиков");
results.modify(res_itr, coopname, [&](auto &r){
r.participants_bonus_remain -= eosio::asset(participant_amount, _root_govern_symbol);
});
// 5) Обновляем reward_per_share_last_* в resactor
auto exist_resactor = get_resactor_or_fail(coopname, result_hash, username, "Объект пайщика в результате не найден");
resactor_index ractors(_capital, coopname.value);
auto ract_it = ractors.find(exist_resactor.id);
ractors.modify(ract_it, same_payer, [&](auto &ra){
// Если действительно происходил прирост (delta>0), обновляем
if (ra.authors_shares > 0) {
int64_t current_crps_auth = res_itr->authors_cumulative_reward_per_share;
int64_t delta_auth = current_crps_auth - ra.reward_per_share_last_authors;
if (delta_auth > 0) {
ra.reward_per_share_last_authors = current_crps_auth;
}
}
if (ra.creators_shares > 0) {
int64_t current_crps_creat = res_itr->creators_cumulative_reward_per_share;
int64_t delta_creat = current_crps_creat - ra.reward_per_share_last_creators;
if (delta_creat > 0) {
ra.reward_per_share_last_creators = current_crps_creat;
}
}
if (ra.participants_shares > 0) {
int64_t current_crps_parts = res_itr->participants_cumulative_reward_per_share;
int64_t delta_parts = current_crps_parts - ra.reward_per_share_last_participants;
if (delta_parts > 0) {
ra.reward_per_share_last_participants = current_crps_parts;
}
}
});
}
@@ -1,3 +1,6 @@
/**
* @brief Принятие второго акта (act2). Убираем любой CRPS, просто плюсуем бонусы.
*/
void capital::setact2(
eosio::name coopname,
eosio::name application,
@@ -8,130 +11,114 @@ void capital::setact2(
check_auth_or_fail(_capital, coopname, application, "setact2"_n);
verify_document_or_fail(act);
// 1) Ищем коммит
// Ищем коммит
auto exist_commit = get_commit(coopname, commit_hash);
eosio::check(exist_commit.has_value(), "Коммит не найден");
eosio::check(exist_commit -> username == username, "Неверно указано имя пользователя владельца результата");
eosio::check(exist_commit -> status == "act1"_n, "Неверный статус для поставки акта");
// 2) Обновляем сам коммит
// Обновляем коммит
commit_index commits(_capital, coopname.value);
auto commit = commits.find(exist_commit -> id);
auto commit = commits.find(exist_commit->id);
commits.modify(commit, coopname, [&](auto &c) {
c.status = "act2"_n;
c.act2 = act;
});
// 3) Ищем результат (или кидаем ошибку) и проект
// Ищем результат и проект
auto exist_result = get_result_or_fail(coopname, commit->result_hash, "Результат не найден");
auto exist_project = get_project(coopname, exist_result.project_hash);
eosio::check(exist_project.has_value(), "Проект не найден");
// 4) Ищем вкладчика
// Ищем вкладчика
auto exist_contributor = get_active_contributor_or_fail(coopname, exist_result.project_hash, commit->username);
contributor_index contributors(_capital, coopname.value);
auto contributor = contributors.find(exist_contributor->id);
// Распределяем spend на available / for_convert
double convert_ratio = double(contributor->convert_percent) / HUNDR_PERCENTS;
asset for_convert(static_cast<int64_t>(commit->spend.amount * convert_ratio), commit->spend.symbol);
asset available = commit->spend - for_convert;
// Обновляем поля вкладчика
contributors.modify(contributor, coopname, [&](auto &c) {
c.available += available;
c.for_convert += for_convert;
c.contributed_hours = commit->contributed_hours;
c.spend += commit->spend;
});
// 5) Вычисляем bonus
// convert_percent — целое число от 0 до HUNDR_PERCENTS
int64_t for_convert_amount = (commit->spend.amount * contributor->convert_percent) / HUNDR_PERCENTS;
eosio::asset for_convert(for_convert_amount, commit->spend.symbol);
eosio::asset available = commit->spend - for_convert;
// Вычисляем bonus
auto br = capital::calculcate_capital_amounts(commit->spend.amount);
eosio::asset creators_bonus(br.creators_bonus, commit->spend.symbol);
eosio::asset authors_bonus(br.authors_bonus, commit->spend.symbol);
eosio::asset generated (br.generated, commit->spend.symbol);
eosio::asset participants_bonus(br.participants_bonus, commit->spend.symbol);
eosio::asset total (br.total, commit->spend.symbol);
eosio::asset creators_bonus (br.creators_bonus, commit->spend.symbol);
eosio::asset authors_bonus (br.authors_bonus, commit->spend.symbol);
eosio::asset generated (br.generated, commit->spend.symbol);
eosio::asset capitalists_bonus (br.capitalists_bonus, commit->spend.symbol);
eosio::asset total (br.total, commit->spend.symbol);
// 6) Обновляем result
// Обновляем result
result_index results(_capital, coopname.value);
auto result = results.find(exist_result.id);
eosio::check(result -> available >= commit->spend, "Недостаточно средств в результате для приёма действия");
eosio::check(result->available >= commit->spend, "Недостаточно средств в результате для приёма коммита");
results.modify(result, coopname, [&](auto &row) {
row.available -= commit->spend;
row.spend += commit->spend;
row.creators_amount += commit->spend;
row.creators_bonus += creators_bonus;
row.authors_bonus += authors_bonus;
row.generated_amount += generated;
row.participants_bonus+= participants_bonus;
row.participants_bonus_remain += participants_bonus;
row.total_amount += total;
row.available -= commit->spend;
row.spend += commit->spend;
row.creators_amount += commit->spend;
row.total_creators_bonus_shares += commit->spend.amount;
row.creators_bonus += creators_bonus;
row.authors_bonus += authors_bonus;
row.generated_amount += generated;
row.capitalists_bonus += capitalists_bonus;
row.total_amount += total;
row.commits_count++;
// CRPS: повышаем cumulative поля
if (row.authors_shares > 0 && authors_bonus.amount > 0) {
int64_t delta_auth = (authors_bonus.amount * REWARD_SCALE) / row.authors_shares;
row.authors_cumulative_reward_per_share += delta_auth;
}
if (row.creators_amount.amount > 0 && creators_bonus.amount > 0) {
int64_t delta_creat = (creators_bonus.amount * REWARD_SCALE) / row.creators_amount.amount;
row.creators_cumulative_reward_per_share += delta_creat;
}
int64_t total_participants_shares = get_capital_program_share_balance(coopname);
if (total_participants_shares > 0 && participants_bonus.amount > 0) {
int64_t delta_part = (participants_bonus.amount * REWARD_SCALE) / total_participants_shares;
row.participants_cumulative_reward_per_share += delta_part;
}
});
// 7) Обновляем проект
// Обновляем проект
project_index projects(_capital, coopname.value);
auto project = projects.find(exist_project->id);
// 8) Обновляем вкладчика и проект (аналог capauthcmmt)
// Обновляем актора и проект
contributors.modify(contributor, coopname, [&](auto &c){
c.spend += commit->spend;
c.share_balance += commit->spend;
c.contributed_hours += commit->contributed_hours;
});
projects.modify(project, coopname, [&](auto &p) {
p.generated += generated;
p.spend += commit->spend;
p.available += commit->spend;
p.membership_total_shares += commit->spend;
p.generated += generated;
p.spend += commit->spend;
p.available += commit->spend;
p.total_share_balance += commit->spend;
});
// 9) Обновляем запись в resactors (создательские доли)
// Обновляем запись в resactors (создательские доли)
auto exist_resactor = get_resactor(coopname, commit->result_hash, commit->username);
resactor_index ractors(_capital, coopname.value);
if (!exist_resactor.has_value()) {
ractors.emplace(coopname, [&](auto &ra){
ra.id = ractors.available_primary_key();
ra.result_hash = commit->result_hash;
ra.username = commit->username;
ra.creators_shares = commit->spend.amount;
ra.id = ractors.available_primary_key();
ra.project_hash = commit->project_hash;
ra.result_hash = commit->result_hash;
ra.username = commit->username;
ra.creators_bonus_shares = commit->spend.amount;
ra.spend = commit->spend;
ra.for_convert = for_convert;
ra.available = available;
ra.contributed_hours = commit->contributed_hours;
});
} else {
auto resactor = ractors.find(exist_resactor -> id);
ractors.modify(resactor, coopname, [&](auto &ra){
ra.creators_shares += commit->spend.amount;
auto resactor = ractors.find(exist_resactor->id);
ractors.modify(resactor, coopname, [&](auto &ra) {
ra.creators_bonus_shares += commit -> spend.amount;
ra.for_convert += for_convert;
ra.available += available;
ra.spend += commit->spend;
ra.contributed_hours += commit->contributed_hours;
});
}
std::string memo = "Приём паевого взноса по договору УХД с contributor_id: " + std::to_string(contributor -> id);
// 10) Добавляем заблокированные средства
// 10) Добавляем заблокированные средства на договор УХД
std::string memo = "Приём паевого взноса по договору УХД с contributor_id: " + std::to_string(contributor->id);
Wallet::add_blocked_funds(_capital, coopname, contributor->username, commit->spend, _source_program, memo);
}
@@ -0,0 +1,48 @@
void capital::approvecnvrt(eosio::name coopname, eosio::name application, eosio::name approver, checksum256 convert_hash, document approved_statement){
check_auth_or_fail(_capital, coopname, application, "approvecnvrt"_n);
verify_document_or_fail(approved_statement);
auto exist_convert = get_convert(coopname, convert_hash);
eosio::check(exist_convert.has_value(), "Конвертация пользователя для результата не найдена");
convert_index converts(_capital, coopname.value);
auto convert = converts.find(exist_convert -> id);
auto result = get_result(coopname, convert -> result_hash);
eosio::check(result.has_value(), "Результат не найден");
// добавляем доли актору и отмечаем статистику сконвертированных сумм
auto contributor = get_active_contributor_or_fail(coopname, convert -> project_hash, convert -> username);
contributor_index contributors(_capital, coopname.value);
auto contributor_for_modify = contributors.find(contributor -> id);
contributors.modify(contributor_for_modify, coopname, [&](auto &c){
c.converted += convert -> convert_amount;
c.share_balance += convert -> convert_amount;
});
// добавляем доли в проект
auto exist = get_project(coopname, convert -> project_hash);
eosio::check(exist.has_value(),"Проект не найден");
project_index projects(_capital, coopname.value);
auto project = projects.find(exist -> id);
projects.modify(project, coopname, [&](auto &p) {
p.converted += convert -> convert_amount;
p.total_share_balance += convert -> convert_amount;
});
std::string memo = "Зачёт части целевого паевого взноса по договору УХД с ID: " + std::to_string(contributor -> id) + " в качестве паевого взноса по программе 'Капитализация' с ID: " + std::to_string(convert -> id);
//Списываем баланс средств с УХД только при наличии convert_amount в claim
Wallet::sub_blocked_funds(_capital, coopname, convert -> username, convert -> convert_amount, _source_program, memo);
//Увеличиваем баланс средств в капитализации
Wallet::add_blocked_funds(_capital, coopname, convert -> username, convert -> convert_amount, _capital_program, memo);
// удаляем объект конвертации
converts.erase(convert);
};
@@ -0,0 +1,67 @@
void capital::createcnvrt(
eosio::name coopname,
eosio::name application,
eosio::name username,
checksum256 result_hash,
checksum256 convert_hash,
document convert_statement
) {
// Авторизация
check_auth_or_fail(_capital, coopname, application, "createcnvrt"_n);
// Получаем результат (или кидаем ошибку)
auto exist_result = get_result_or_fail(coopname, result_hash, "Результат не найден");
eosio::check(exist_result.status == "opened"_n || exist_result.status == "created"_n, "Распределение стоимости результата еще не начато или уже завершено");
// Проверяем, нет ли уже такой конвертации
auto existing_convert = get_convert(coopname, convert_hash);
eosio::check(!existing_convert.has_value(), "Объект конвертации с указанным хэшем уже существует");
// Находим запись в таблице results
result_index results(_capital, coopname.value);
auto result = results.find(exist_result.id);
// Получаем контрибьютора
auto exist_contributor = get_active_contributor_or_fail(coopname, exist_result.project_hash, username);
contributor_index contributors(_capital, coopname.value);
auto contributor = contributors.find(exist_contributor->id);
// Попробуем найти resactor
auto exist_resactor = get_resactor_or_fail(coopname, result_hash, username, "Объект актора в результате не найден");
//=== Сумма к конвертации ===
asset convert_amount = exist_resactor.available + exist_resactor.for_convert;
eosio::check(convert_amount.amount > 0, "Нет доступных средств для конвертации");
//=== Создаём запись в converts ===
convert_index converts(_capital, coopname.value);
uint64_t convert_id = get_global_id_in_scope(_capital, coopname, "converts"_n);
converts.emplace(coopname, [&](auto &n) {
n.id = convert_id;
n.username = username;
n.project_hash = exist_result.project_hash;
n.result_hash = result_hash;
n.convert_hash = convert_hash;
n.coopname = coopname;
n.status = "created"_n;
n.convert_amount = convert_amount;
n.convert_statement = convert_statement;
});
eosio::check(result -> creators_amount_remain >= convert_amount, "Недостаточно средств в result.creators_amount_remain для конвертации");
results.modify(result, coopname, [&](auto &r) {
r.creators_amount_remain -= convert_amount;
});
resactor_index ractors(_capital, coopname.value);
auto resactor = ractors.find(exist_resactor.id);
//обнуляем доступные средства к выводу или конвертации
ractors.modify(resactor, coopname, [&](auto &ra) {
ra.for_convert = asset(0, _root_govern_symbol);
ra.available = asset(0, _root_govern_symbol);
});
}
@@ -3,16 +3,16 @@ void capital::fundprog(eosio::name coopname, asset amount, std::string memo) {
Wallet::validate_asset(amount);
int64_t membership_total_shares = get_capital_program_share_balance(coopname);
int64_t total_share_balance = get_capital_program_share_balance(coopname);
auto state = get_global_state(coopname);
state.program_membership_funded += amount;
state.program_membership_available += amount;
if (membership_total_shares > 0) {
if (total_share_balance > 0) {
// REWARD_SCALE - ваш масштаб (например, 1e8), чтобы не терять точность
int64_t delta = (amount.amount * REWARD_SCALE) / membership_total_shares;
int64_t delta = (amount.amount * REWARD_SCALE) / total_share_balance;
state.program_membership_cumulative_reward_per_share += delta;
};
@@ -1,15 +1,15 @@
[[eosio::action]] void capital::refreshprog(name coopname, name application, name username) {
check_auth_or_fail(_capital, coopname, application, "refreshprog"_n);
// Находим участника в программе
capital_tables::participant_index participants(_capital, coopname.value);
auto participant = participants.find(username.value);
// Находим капиталиста в программе
capital_tables::capitalist_index capitalists(_capital, coopname.value);
auto capitalist = capitalists.find(username.value);
auto state = get_global_state(coopname);
// 3. Считаем дельту CRPS
int64_t current_crps = state.program_membership_cumulative_reward_per_share;
int64_t last_crps = participant == participants.end() ? 0 : participant -> reward_per_share_last;
int64_t last_crps = capitalist == capitalists.end() ? 0 : capitalist -> reward_per_share_last;
int64_t delta = current_crps - last_crps;
int64_t share_balance = get_capital_user_share_balance(coopname, username);
@@ -18,18 +18,16 @@
// Начисляем вознаграждение
int64_t reward_amount_int = (share_balance * delta) / REWARD_SCALE;
asset reward_amount = asset(reward_amount_int, _root_govern_symbol);
if (participant == participants.end()){
//добавляем объект учёта вознаграждений пайщика по ЦПП Капитализации
participants.emplace(coopname, [&](auto &p){
if (capitalist == capitalists.end()){
capitalists.emplace(coopname, [&](auto &p){
p.username = username;
p.coopname = coopname;
p.pending_rewards = reward_amount;
p.reward_per_share_last = current_crps;
});
} else {
// Обновляем объект учёта вознаграждений пайщика по ЦПП Капитализации
participants.modify(participant, coopname, [&](auto &p) {
capitalists.modify(capitalist, coopname, [&](auto &p) {
p.pending_rewards += reward_amount;
p.reward_per_share_last = current_crps;
});
@@ -27,8 +27,8 @@ void capital::distribute_project_membership_funds(eosio::name coopname, uint64_t
p.membership_funded += amount;
p.membership_available += membership_current_fund;
if (project -> membership_total_shares.amount > 0) {
int64_t delta = (membership_current_fund.amount * REWARD_SCALE) / project->membership_total_shares.amount;
if (project -> total_share_balance.amount > 0) {
int64_t delta = (membership_current_fund.amount * REWARD_SCALE) / project->total_share_balance.amount;
p.membership_cumulative_reward_per_share += delta;
};
});
@@ -32,7 +32,7 @@ void capital::capauthinvst(eosio::name coopname, uint64_t invest_id, document au
p.available += invest -> amount;
// добавляем новые доли в проект
p.membership_total_shares += invest -> amount;
p.total_share_balance += invest -> amount;
});
std::string memo = "Зачёт части целевого паевого взноса по программе 'Цифровой Кошелёк' в качестве паевого взноса по договору УХД с contributor_id:" + std::to_string(contributor -> id);
@@ -26,7 +26,7 @@ void capital::addauthor(name coopname, name application, checksum256 project_has
// Обновляем shares и authors_count в проекте
projects.modify(project_for_modify, coopname, [&](auto& row) {
row.authors_shares += shares;
row.authors_count++;
row.authors_shares += shares;
row.authors_count++;
});
}
@@ -24,23 +24,23 @@ void capital::createresult(name coopname, name application, checksum256 project_
// Перебираем всех авторов с данным project_hash
auto author_itr = authors_hash_index.lower_bound(project_hash);
result_authors_index result_authors(_capital, coopname.value);
uint64_t authors_count = 0;
resactor_index ractors(_capital, coopname.value);
// Копируем запись автора идеи в result_authors
while(author_itr != authors_hash_index.end() && author_itr->project_hash == project_hash) {
result_authors.emplace(coopname, [&](auto &n){
n.id = get_global_id_in_scope(_capital, coopname, "resauthors"_n);
n.username = author_itr->username;
n.result_hash = result_hash;
n.project_hash = project_hash;
n.shares = author_itr -> shares;
ractors.emplace(coopname, [&](auto &ra){
ra.id = ractors.available_primary_key();
ra.result_hash = result_hash;
ra.project_hash = project_hash;
ra.username = author_itr->username;
ra.authors_shares = author_itr -> shares;
});
authors_count++;
author_itr++;
}
eosio::check(authors_count > 0, "Нельзя создать результат без установленных авторов в проекте");
}
@@ -1,24 +1,21 @@
void capital::startdistrbn(name coopname, name application, checksum256 result_hash) {
// check_auth_or_fail(_capital, coopname, application, "start"_n);
check_auth_or_fail(_capital, coopname, application, "start"_n);
// auto result = get_result(coopname, result_hash);
// eosio::check(result.has_value(), "Результат не найден");
// eosio::check(result -> status == "created"_n, "Только результат в статусе created может быть запущен в распределение");
auto result = get_result(coopname, result_hash);
eosio::check(result.has_value(), "Результат не найден");
eosio::check(result -> status == "created"_n, "Только результат в статусе created может быть запущен в распределение");
// auto project = get_project(coopname, result -> project_hash);
// eosio::check(project.has_value(), "проект не найден");
auto project = get_project(coopname, result -> project_hash);
eosio::check(project.has_value(), "проект не найден");
// result_index results(_capital, coopname.value);
// auto result_for_modify = results.find(result -> id);
result_index results(_capital, coopname.value);
auto result_for_modify = results.find(result -> id);
// results.modify(result_for_modify, coopname, [&](auto& row) {
// row.status = "started"_n;
// });
// projects_index projects(_capital, coopname.value);
// auto project_for_modify = projects.find(project -> id);
// projects.modify(project_for_modify, coopname, [&](auto &p) {
// p.available =
// });
results.modify(result_for_modify, coopname, [&](auto& row) {
row.status = "opened"_n;
row.authors_bonus_remain = row.authors_bonus;
row.creators_amount_remain = row.creators_amount;
row.creators_bonus_remain = row.creators_bonus;
row.capitalists_bonus_remain = row.capitalists_bonus;
});
};
@@ -1,50 +1,14 @@
void capital::capauthwthd3(eosio::name coopname, uint64_t withdraw_id, document authorization) {
void capital::capauthwthd3(name coopname, uint64_t withdraw_id, document authorization) {
require_auth(_soviet);
capital_tables::program_withdraws_index program_withdraws(_capital, coopname.value);
auto withdraw = program_withdraws.find(withdraw_id);
eosio::check(withdraw != program_withdraws.end(), "Объект возврата не найден");
capital_tables::participant_index participants(_capital, coopname.value);
auto participant = participants.find(withdraw -> username.value);
int64_t share_balance = get_capital_user_share_balance(coopname, withdraw -> username);
eosio::check(share_balance >= withdraw -> amount.amount, "Недостаточно долей для уменьшения");
participants.modify(participant, coopname, [&](auto &c) {
c.returned_rewards += withdraw -> amount;
});
//Уменьшение доли share_balance у пользователя и total_share_balances в проекте
auto state = get_global_state(coopname);
//извлекаем общее количество долей всех пайщиков в капитализации
auto program_share_balance = get_capital_program_share_balance(coopname);
int64_t prev_total_shares = program_share_balance;
int64_t new_total_shares = prev_total_shares - withdraw -> amount.amount;
eosio::check(new_total_shares >= 0, "Нельзя уменьшить total_shares ниже 0");
if (new_total_shares > 0) {
state.program_membership_cumulative_reward_per_share = state.program_membership_cumulative_reward_per_share * prev_total_shares / new_total_shares;
} else {
state.program_membership_cumulative_reward_per_share = 0;
}
// обновляем глобальное состояние программы
update_global_state(state);
std::string memo = "Зачёт части целевого паевого взноса по программе 'Капитализация' в качестве паевого взноса по программе 'Цифровой Кошелёк' с ID: " + std::to_string(withdraw_id);
// списание с капитализации
Wallet::sub_blocked_funds(_capital, coopname, withdraw -> username, withdraw -> amount, _capital_program, memo);
// добавление в кошелёк
Wallet::add_available_funds(_capital, coopname, withdraw -> username, withdraw -> amount, _wallet_program, memo);
// удаление возврата
Wallet::sub_blocked_funds(_capital, coopname, withdraw->username, withdraw->amount, _capital_program, memo);
Wallet::add_available_funds(_capital, coopname, withdraw->username, withdraw->amount, _wallet_program, memo);
program_withdraws.erase(withdraw);
}
@@ -5,20 +5,52 @@ void capital::createwthd3(name coopname, name application, name username, checks
auto exist_project = get_project(coopname, project_hash);
eosio::check(exist_project.has_value(), "Проект с указанным хэшем не найден");
capital_tables::participant_index participants(_capital, coopname.value);
auto participant = participants.find(username.value);
eosio::check(participant -> pending_rewards >= amount, "Недостаточно накопленных средств для создания запроса на возврат");
participants.modify(participant, coopname, [&](auto &c) {
capital_tables::capitalist_index capitalists(_capital, coopname.value);
auto capitalist = capitalists.find(username.value);
eosio::check(capitalist != capitalists.end(), "Капиталист не найден");
eosio::check(capitalist -> pending_rewards >= amount, "Недостаточно накопленных средств для создания запроса на возврат");
int64_t share_balance = get_capital_user_share_balance(coopname, username);
eosio::check(share_balance >= amount.amount, "Недостаточно долей для уменьшения");
// Обновление данных капиталиста
capitalists.modify(capitalist, coopname, [&](auto &c) {
c.pending_rewards -= amount;
c.returned_rewards += amount;
});
// Обновление глобального состояния
auto state = get_global_state(coopname);
auto program_share_balance = get_capital_program_share_balance(coopname);
int64_t prev_total_shares = program_share_balance;
int64_t new_total_shares = prev_total_shares - amount.amount;
eosio::check(new_total_shares >= 0, "Нельзя уменьшить total_shares ниже 0");
const int64_t PRECISION = 100000000; // 1e8 — масштаб фиксированной дроби
if (new_total_shares > 0) {
eosio::check(state.program_membership_cumulative_reward_per_share >= 0, "Некорректное значение reward_per_share");
// Переводим значение в фиксированную точку
int128_t base = static_cast<int128_t>(state.program_membership_cumulative_reward_per_share);
int128_t scaled = base * PRECISION;
int128_t scaled_result = (scaled * prev_total_shares) / new_total_shares;
// Обратно в i64, округляя
state.program_membership_cumulative_reward_per_share = static_cast<int64_t>(scaled_result / PRECISION);
} else {
state.program_membership_cumulative_reward_per_share = 0;
}
update_global_state(state);
auto exist_withdraw = get_program_withdraw(coopname, withdraw_hash);
eosio::check(!exist_withdraw.has_value(), "Заявка на возврат с таким хэшем уже существует");
capital_tables::program_withdraws_index program_withdraws(_capital, coopname.value);
program_withdraws.emplace(coopname, [&](auto &w) {
@@ -29,4 +61,5 @@ void capital::createwthd3(name coopname, name application, name username, checks
w.amount = amount;
w.return_statement = return_statement;
});
}
}
@@ -1,58 +1,14 @@
void capital::capauthwthd2(eosio::name coopname, uint64_t withdraw_id, document authorization) {
void capital::capauthwthd2(name coopname, uint64_t withdraw_id, document authorization) {
require_auth(_soviet);
capital_tables::project_withdraws_index project_withdraws(_capital, coopname.value);
auto withdraw = project_withdraws.find(withdraw_id);
eosio::check(withdraw != project_withdraws.end(), "Объект возврата не найден");
auto exist_contributor = capital::get_active_contributor_or_fail(coopname, withdraw -> project_hash, withdraw -> username);
contributor_index contributors(_capital, coopname.value);
auto contributor = contributors.find(exist_contributor -> id);
eosio::check(contributor->share_balance >= withdraw -> amount, "Недостаточно долей для уменьшения");
std::string memo = "Зачёт части целевого паевого взноса по программе 'Капитализация' в качестве паевого взноса по участию в 'Цифровой Кошелёк'";
contributors.modify(contributor, coopname, [&](auto &c) {
c.returned += withdraw -> amount;
c.share_balance -= withdraw -> amount;
});
//Уменьшение доли share_balance у пользователя и total_share_balances в проекте
auto exist_project = get_project(coopname, withdraw -> project_hash);
eosio::check(exist_project.has_value(), "Проект не найден");
Wallet::sub_blocked_funds(_capital, coopname, withdraw->username, withdraw->amount, _capital_program, memo);
Wallet::add_available_funds(_capital, coopname, withdraw->username, withdraw->amount, _wallet_program, memo);
project_index projects(_capital, coopname.value);
auto project = projects.find(exist_project->id);
int64_t prev_total_shares = project -> membership_total_shares.amount;
int64_t new_total_shares = prev_total_shares - withdraw -> amount.amount;
eosio::check(new_total_shares >= 0, "Нельзя уменьшить total_shares ниже 0");
// Пересчёт cumulative_reward_per_share для корректного распределения будущих выплат
if (new_total_shares > 0) {
projects.modify(project, coopname, [&](auto &p) {
p.membership_cumulative_reward_per_share =
(p.membership_cumulative_reward_per_share * prev_total_shares) / new_total_shares;
p.membership_total_shares -= withdraw -> amount;
});
} else {
// Если все доли исчезли, просто обнуляем
projects.modify(project, coopname, [&](auto &p) {
p.membership_cumulative_reward_per_share = 0;
p.membership_total_shares = asset(0, _root_govern_symbol);
});
}
std::string memo = "Зачёт части целевого паевого взноса по программе 'Капитализация' в качестве паевого взноса по участию в 'Цифровой Кошелёк' с ID: " + std::to_string(withdraw_id);
// списание с капитализации
Wallet::sub_blocked_funds(_capital, coopname, withdraw -> username, withdraw -> amount, _capital_program, memo);
// добавление в кошелёк
Wallet::add_available_funds(_capital, coopname, withdraw -> username, withdraw -> amount, _wallet_program, memo);
// удаление возврата
project_withdraws.erase(withdraw);
}
@@ -5,24 +5,47 @@ void capital::createwthd2(name coopname, name application, name username, checks
auto exist_project = get_project(coopname, project_hash);
eosio::check(exist_project.has_value(), "Проект с указанным хэшем не найден");
auto exist_contributor = capital::get_active_contributor_or_fail(coopname, project_hash, username);
eosio::check(exist_contributor -> pending_rewards >= amount, "Недостаточно накопленных средств для создания запроса на возврат");
contributor_index contributors(_capital, coopname.value);
auto contributor = contributors.find(exist_contributor -> id);
eosio::check(contributor->share_balance >= amount, "Недостаточно долей для уменьшения");
// Обновление долей
contributors.modify(contributor, coopname, [&](auto &c) {
c.pending_rewards -= amount;
c.returned += amount;
c.share_balance -= amount;
});
// Обновление проекта
project_index projects(_capital, coopname.value);
auto project = projects.find(exist_project->id);
int64_t prev_total_shares = project->total_share_balance.amount;
int64_t new_total_shares = prev_total_shares - amount.amount;
eosio::check(new_total_shares >= 0, "Нельзя уменьшить total_shares ниже 0");
if (new_total_shares > 0) {
projects.modify(project, coopname, [&](auto &p) {
p.membership_cumulative_reward_per_share = (p.membership_cumulative_reward_per_share * prev_total_shares) / new_total_shares;
p.total_share_balance -= amount;
});
} else {
projects.modify(project, coopname, [&](auto &p) {
p.membership_cumulative_reward_per_share = 0;
p.total_share_balance = asset(0, _root_govern_symbol);
});
}
// Запись возврата
auto exist_withdraw = get_result_withdraw(coopname, withdraw_hash);
eosio::check(!exist_withdraw.has_value(), "Заявка на взнос-возврат с таким хэшем уже существует");
capital_tables::project_withdraws_index project_withdraws(_capital, coopname.value);
project_withdraws.emplace(coopname, [&](auto &w) {
w.id = get_global_id_in_scope(_capital, coopname, "withdraws2"_n);
w.coopname = coopname;
@@ -32,4 +55,4 @@ void capital::createwthd2(name coopname, name application, name username, checks
w.amount = amount;
w.return_statement = return_statement;
});
}
}
@@ -1,7 +1,6 @@
void capital::approvewthd1(name coopname, name application, name approver, checksum256 withdraw_hash, document approved_contribution_statement, document approved_return_statement) {
void capital::approvewthd1(name coopname, name application, name approver, checksum256 withdraw_hash, document approved_return_statement) {
check_auth_or_fail(_capital, coopname, application, "approvewthd1"_n);
verify_document_or_fail(approved_contribution_statement);
verify_document_or_fail(approved_return_statement);
auto exist_withdraw = get_result_withdraw(coopname, withdraw_hash);
@@ -12,17 +11,12 @@ void capital::approvewthd1(name coopname, name application, name approver, check
result_withdraws.modify(withdraw, coopname, [&](auto &i) {
i.status = "approved"_n;
i.approved_contribution_statement = approved_contribution_statement;
i.approved_return_statement = approved_return_statement;
});
//отправляем в совет
action(permission_level{ _capital, "active"_n}, _soviet, _capital_withdraw_from_result_authorize_contribution_action,
std::make_tuple(coopname, withdraw -> username, withdraw -> id, withdraw -> contribution_statement, std::string("")))
action(permission_level{ _capital, "active"_n}, _soviet, "createagenda"_n,
std::make_tuple(coopname, withdraw -> username, _capital, _capital_withdraw_from_result_authorize_action, withdraw -> id, withdraw -> return_statement, std::string("")))
.send();
action(permission_level{ _capital, "active"_n}, _soviet, _capital_withdraw_from_result_authorize_return_action,
std::make_tuple(coopname, withdraw -> username, withdraw -> id, withdraw -> return_statement, std::string("")))
.send();
};
@@ -1,42 +0,0 @@
// действие авторизации возврата вызывается после получения авторизаций совета на взнос и возврат взноса
void capital::authwithdrw1(eosio::name coopname, checksum256 withdraw_hash) {
require_auth(_capital);
auto exist_withdraw = get_result_withdraw(coopname, withdraw_hash);
eosio::check(exist_withdraw.has_value(), "Объект взноса-возврата не найден");
capital_tables::result_withdraws_index result_withdraws(_capital, coopname.value);
auto withdraw = result_withdraws.find(exist_withdraw -> id);
//обновить сумму выводов по проекту
auto exist_project = get_project(coopname, withdraw -> project_hash);
project_index projects(_capital, coopname.value);
auto project = projects.find(exist_project->id);
projects.modify(project, _capital, [&](auto &p){
p.spend += withdraw -> amount;
});
auto exist_contributor = capital::get_active_contributor_or_fail(coopname, withdraw -> project_hash, withdraw -> username);
contributor_index contributors(_capital, coopname.value);
auto contributor = contributors.find(exist_contributor -> id);
contributors.modify(contributor, coopname, [&](auto &c) {
c.withdrawed += withdraw -> amount;
});
std::string memo_in = "Приём паевого взноса по договору УХД с ID: " + std::to_string(contributor -> id);
Wallet::add_blocked_funds(_capital, coopname, withdraw->username, withdraw->amount, _source_program, memo_in);
// списание с УХД
std::string memo_out = "Возврат части паевого взноса по договору УХД с ID: " + std::to_string(contributor -> id);
Wallet::sub_blocked_funds(_capital, coopname, withdraw -> username, withdraw -> amount, _source_program, memo_out);
// добавление в кошелёк
Wallet::add_available_funds(_capital, coopname, withdraw -> username, withdraw -> amount, _wallet_program, memo_out);
result_withdraws.erase(withdraw);
}
@@ -0,0 +1,22 @@
void capital::capauthwthd1(eosio::name coopname, uint64_t withdraw_id, document authorization) {
require_auth(_soviet);
//Получаем объект возврата
capital_tables::result_withdraws_index result_withdraws(_capital, coopname.value);
auto withdraw = result_withdraws.find(withdraw_id);
eosio::check(withdraw != result_withdraws.end(), "Объект взноса-возврата не найден");
auto exist_contributor = capital::get_active_contributor_or_fail(coopname, withdraw -> project_hash, withdraw -> username);
auto exist_result = get_result_or_fail(coopname, withdraw -> result_hash, "Результат не найден");
// списание с УХД
std::string memo_out = "Зачёт части целевого паевого взноса по договору УХД с ID: " + std::to_string(exist_contributor -> id) + " в качестве паевого взноса по программе 'Цифровой Кошелёк'";
// списываем с кошелька программы генерации при договоре УХД
Wallet::sub_blocked_funds(_capital, coopname, withdraw -> username, withdraw -> amount, _source_program, memo_out);
// добавление в кошелёк
Wallet::add_available_funds(_capital, coopname, withdraw -> username, withdraw -> amount, _wallet_program, memo_out);
result_withdraws.erase(withdraw);
}
@@ -1,13 +0,0 @@
void capital::capauthwthdc(eosio::name coopname, uint64_t withdraw_id, document authorization) {
require_auth(_soviet);
capital_tables::result_withdraws_index result_withdraws(_capital, coopname.value);
auto withdraw = result_withdraws.find(withdraw_id);
eosio::check(withdraw != result_withdraws.end(), "Объект взноса-возврата не найден");
result_withdraws.modify(withdraw, _capital, [&](auto &w){
w.authorized_contribution_statement = authorization;
});
capital::try_finalize_withdrawal(coopname, withdraw);
}
@@ -1,13 +0,0 @@
void capital::capauthwthdr(eosio::name coopname, uint64_t withdraw_id, document authorization) {
require_auth(_soviet);
capital_tables::result_withdraws_index result_withdraws(_capital, coopname.value);
auto withdraw = result_withdraws.find(withdraw_id);
eosio::check(withdraw != result_withdraws.end(), "Объект взноса-возврата не найден");
result_withdraws.modify(withdraw, _capital, [&](auto &w){
w.authorized_return_statement = authorization;
});
try_finalize_withdrawal(coopname, withdraw);
}
@@ -1,38 +1,61 @@
void capital::createwthd1(eosio::name coopname, eosio::name application, eosio::name username, checksum256 result_hash, checksum256 withdraw_hash, std::vector<checksum256> commit_hashes, document contribution_statement, document return_statement) {
void capital::createwthd1(eosio::name coopname, eosio::name application, eosio::name username, checksum256 result_hash, checksum256 withdraw_hash, asset amount, document return_statement) {
check_auth_or_fail(_capital, coopname, application, "createwthd1"_n);
verify_document_or_fail(contribution_statement);
verify_document_or_fail(return_statement);
Wallet::validate_asset(amount);
auto exist_result = get_result(coopname, result_hash);
eosio::check(exist_result.has_value(), "Результат с указанным хэшем не найден");
auto exist_project = get_project(coopname, exist_result -> project_hash);
eosio::check(exist_project.has_value(), "Проект с указанным хэшем не найден");
auto exist_contributor = capital::get_active_contributor_or_fail(coopname, exist_result -> project_hash, username);
eosio::asset amount = asset(0, _root_govern_symbol);
uint64_t count = 0;
for (const auto& commit_hash : commit_hashes) {
amount += get_amount_for_withdraw_from_commit(coopname, username, commit_hash);
count++;
eosio::check(count <= 20, "Нельзя оформить более 20 коммитов на раз");
}
contributor_index contributors(_capital, coopname.value);
auto contributor = contributors.find(exist_contributor -> id);
eosio::check(contributor -> available >= amount, "Недостаточно средств для создания запроса на материальную помощь");
contributors.modify(contributor, coopname, [&](auto &c) {
c.available -= amount;
//обновить сумму выводов по проекту
project_index projects(_capital, coopname.value);
auto project = projects.find(exist_project->id);
eosio::check(project -> total_share_balance >= amount, "Недостаточно средств в project.total_share_balance проекта для осуществления возврата");
projects.modify(project, _capital, [&](auto &p){
p.withdrawed += amount;
p.total_share_balance -= amount;
});
auto exist_contributor = capital::get_active_contributor_or_fail(coopname, exist_result -> project_hash, username);
contributor_index contributors(_capital, coopname.value);
auto contributor = contributors.find(exist_contributor -> id);
eosio::check(contributor -> share_balance >= amount, "Недостаточно средств в contributor.share_balance для осуществления возврата");
contributors.modify(contributor, coopname, [&](auto &c) {
c.withdrawed += amount;
c.share_balance -= amount;
});
auto exist_resactor = get_resactor_or_fail(coopname, exist_result->result_hash, username, "Объект актора в результате не найден");
resactor_index ractors(_capital, coopname.value);
auto resactor = ractors.find(exist_resactor.id);
eosio::check(resactor -> available >= amount, "Недостаточно средств для создания возврата");
eosio::check(resactor -> creators_bonus_shares >= amount.amount, "Недостаточно средств в creators_bonus_shares для создания возврата");
ractors.modify(resactor, coopname, [&](auto &ra) {
ra.available -= amount;
ra.creators_bonus_shares -= amount.amount;
});
result_index results(_capital, coopname.value);
auto result = results.find(exist_result -> id);
eosio::check(result -> total_creators_bonus_shares >= amount.amount, "Недостаточное количество result -> total_creators_bonus_shares для осуществления возврата");
results.modify(result, coopname, [&](auto &row) {
row.total_creators_bonus_shares -= amount.amount;
});
auto exist_withdraw = get_result_withdraw(coopname, withdraw_hash);
eosio::check(!exist_withdraw.has_value(), "Заявка на взнос-возврат с таким хэшем уже существует");
eosio::check(!exist_withdraw.has_value(), "Заявка на возврат с таким хэшем уже существует");
capital_tables::result_withdraws_index result_withdraws(_capital, coopname.value);
@@ -40,12 +63,10 @@ void capital::createwthd1(eosio::name coopname, eosio::name application, eosio::
w.id = get_global_id_in_scope(_capital, coopname, "withdraws1"_n);
w.coopname = coopname;
w.withdraw_hash = withdraw_hash;
w.commit_hashes = commit_hashes;
w.result_hash = result_hash;
w.project_hash = exist_result -> project_hash;
w.username = username;
w.amount = amount;
w.contribution_statement = contribution_statement;
w.return_statement = return_statement;
});
};
+1 -2
View File
@@ -79,8 +79,7 @@ static constexpr eosio::name _product_return_action = "productrtrn"_n;
// capitalization linked actions
static constexpr eosio::name _capital_contributor_authorize_action = "capregcontr"_n;
static constexpr eosio::name _capital_invest_authorize_action = "capauthinvst"_n;
static constexpr eosio::name _capital_withdraw_from_result_authorize_contribution_action = "capauthwthdc"_n;
static constexpr eosio::name _capital_withdraw_from_result_authorize_return_action = "capauthwthdr"_n;
static constexpr eosio::name _capital_withdraw_from_result_authorize_action = "capauthwthd1"_n;
static constexpr eosio::name _capital_expense_authorize_action = "capauthexpns"_n;
static constexpr eosio::name _capital_commit_authorize_action = "capauthcmmt"_n;
@@ -17,8 +17,6 @@
#include "src/decisions.cpp"
#include "src/branch.cpp"
#include "src/capital.cpp"
#include "src/capital/capauthwthdc.cpp"
#include "src/capital/capauthwthdr.cpp"
#include "src/openprogwall.cpp"
#include "src/agenda.cpp"
@@ -249,10 +247,6 @@ void soviet::exec(eosio::name executer, eosio::name coopname, uint64_t decision_
soviet::subaccum_effect(executer, coopname, decision->id, decision->batch_id);
} else if (decision -> type == _free_decision_action) {//операция свободного решения
soviet::freedecision_effect(executer, coopname, decision->id);
} else if (decision -> type == _capital_withdraw_from_result_authorize_contribution_action) {//операция взноса в момент вывода по контракту капитализации
soviet::capital_contribute_on_withdraw_effect(executer, coopname, decision -> id);
} else if (decision -> type == _capital_withdraw_from_result_authorize_return_action) {//операция взноса в момент вывода по контракту капитализации
soviet::capital_return_on_withdraw_effect(executer, coopname, decision -> id);
} else if (decision -> type == _capital_contributor_authorize_action) {//операция регистрации контрибьютора (заключение договора УХД)
soviet::capital_register_contributor_authorize_action_effect(executer, coopname, decision -> id);
} else if (decision -> type == _capital_invest_authorize_action) {//операция приёма паевого взноса с кошелька на проект
@@ -150,7 +150,6 @@ public:
[[eosio::action]] void deletebranch(eosio::name coopname, eosio::name braname);
//capital.cpp
void capital_contribute_on_withdraw_effect(eosio::name executer, eosio::name coopname, uint64_t decision_id);
void capital_return_on_withdraw_effect(eosio::name executer, eosio::name coopname, uint64_t decision_id);
[[eosio::action]] void capregcontr(eosio::name coopname, eosio::name username, uint64_t contributor_id, document statement, std::string meta);
@@ -158,11 +157,6 @@ public:
void capital_invest_authorize_action_effect(eosio::name executer, eosio::name coopname, uint64_t decision_id);
[[eosio::action]] void capauthinvst(eosio::name coopname, eosio::name username, uint64_t invest_id, document statement, std::string meta);
[[eosio::action]] void capauthwthdc(eosio::name coopname, eosio::name username, uint64_t withdraw_id, document statement, std::string meta);
[[eosio::action]] void capauthwthdr(eosio::name coopname, eosio::name username, uint64_t withdraw_id, document statement, std::string meta);
};
@@ -1,59 +0,0 @@
[[eosio::action]] void soviet::capauthwthdc(eosio::name coopname, eosio::name username, uint64_t withdraw_id, document statement, std::string meta) {
require_auth(_capital);
decisions_index decisions(_soviet, coopname.value);
auto decision_id = get_id(_soviet, coopname, "decisions"_n);
decisions.emplace(_soviet, [&](auto &d){
d.id = decision_id;
d.coopname = coopname;
d.username = username;
d.type = _capital_withdraw_from_result_authorize_contribution_action;
d.batch_id = withdraw_id;
d.statement = statement;
d.created_at = eosio::time_point_sec(eosio::current_time_point().sec_since_epoch());
d.expired_at = eosio::time_point_sec(eosio::current_time_point().sec_since_epoch() + _decision_expiration);
d.meta = meta;
});
action(
permission_level{ _soviet, "active"_n},
_soviet,
"newsubmitted"_n,
std::make_tuple(coopname, username, _capital_withdraw_from_result_authorize_contribution_action, decision_id, statement)
).send();
}
void soviet::capital_contribute_on_withdraw_effect(eosio::name executer, eosio::name coopname, uint64_t decision_id) {
decisions_index decisions(_soviet, coopname.value);
auto decision = decisions.find(decision_id);
action(
permission_level{ _soviet, "active"_n},
_capital,
_capital_withdraw_from_result_authorize_contribution_action,
std::make_tuple(coopname, decision -> batch_id, decision -> authorization)
).send();
action(
permission_level{ _soviet, "active"_n},
_soviet,
"newresolved"_n,
std::make_tuple(coopname, decision -> username, decision -> type, decision_id, decision -> statement)
).send();
action(
permission_level{ _soviet, "active"_n},
_soviet,
"newdecision"_n,
std::make_tuple(coopname, decision -> username, decision -> type, decision_id, decision -> authorization)
).send();
decisions.erase(decision);
};
@@ -1,58 +0,0 @@
[[eosio::action]] void soviet::capauthwthdr(eosio::name coopname, eosio::name username, uint64_t withdraw_id, document statement, std::string meta) {
require_auth(_capital);
decisions_index decisions(_soviet, coopname.value);
auto decision_id = get_id(_soviet, coopname, "decisions"_n);
decisions.emplace(_soviet, [&](auto &d){
d.id = decision_id;
d.coopname = coopname;
d.username = username;
d.type = _capital_withdraw_from_result_authorize_return_action;
d.batch_id = withdraw_id;
d.statement = statement;
d.created_at = eosio::time_point_sec(eosio::current_time_point().sec_since_epoch());
d.expired_at = eosio::time_point_sec(eosio::current_time_point().sec_since_epoch() + _decision_expiration);
d.meta = meta;
});
action(
permission_level{ _soviet, "active"_n},
_soviet,
"newsubmitted"_n,
std::make_tuple(coopname, username, _capital_withdraw_from_result_authorize_return_action, decision_id, statement)
).send();
}
void soviet::capital_return_on_withdraw_effect(eosio::name executer, eosio::name coopname, uint64_t decision_id) {
decisions_index decisions(_soviet, coopname.value);
auto decision = decisions.find(decision_id);
action(
permission_level{ _soviet, "active"_n},
_capital,
_capital_withdraw_from_result_authorize_return_action,
std::make_tuple(coopname, decision -> batch_id, decision -> authorization)
).send();
action(
permission_level{ _soviet, "active"_n},
_soviet,
"newresolved"_n,
std::make_tuple(coopname, decision -> username, decision -> type, decision_id, decision -> statement)
).send();
action(
permission_level{ _soviet, "active"_n},
_soviet,
"newdecision"_n,
std::make_tuple(coopname, decision -> username, decision -> type, decision_id, decision -> authorization)
).send();
decisions.erase(decision);
};
+76 -54
View File
@@ -30,7 +30,8 @@ export interface IApproveclaim {
coopname: IName
application: IName
approver: IName
claim_hash: IChecksum256
username: IName
result_hash: IChecksum256
approved_statement: IDocument
}
@@ -42,6 +43,14 @@ export interface IApprovecmmt {
approved_statement: IDocument
}
export interface IApprovecnvrt {
coopname: IName
application: IName
approver: IName
convert_hash: IChecksum256
approved_statement: IDocument
}
export interface IApproveexpns {
coopname: IName
application: IName
@@ -72,7 +81,6 @@ export interface IApprovewthd1 {
application: IName
approver: IName
withdraw_hash: IChecksum256
approved_contribution_statement: IDocument
approved_return_statement: IDocument
}
@@ -99,11 +107,6 @@ export interface IAuthor {
shares: IUint64
}
export interface IAuthwithdrw1 {
coopname: IName
withdraw_hash: IChecksum256
}
export interface ICapauthclaim {
coopname: IName
claim_id: IUint64
@@ -128,6 +131,12 @@ export interface ICapauthinvst {
authorization: IDocument
}
export interface ICapauthwthd1 {
coopname: IName
withdraw_id: IUint64
authorization: IDocument
}
export interface ICapauthwthd2 {
coopname: IName
withdraw_id: IUint64
@@ -140,16 +149,12 @@ export interface ICapauthwthd3 {
authorization: IDocument
}
export interface ICapauthwthdc {
export interface ICapitalist {
username: IName
coopname: IName
withdraw_id: IUint64
authorization: IDocument
}
export interface ICapauthwthdr {
coopname: IName
withdraw_id: IUint64
authorization: IDocument
pending_rewards: IAsset
returned_rewards: IAsset
reward_per_share_last: IInt64
}
export interface ICapregcontr {
@@ -160,7 +165,6 @@ export interface ICapregcontr {
export interface IClaim {
id: IUint64
claim_hash: IChecksum256
project_hash: IChecksum256
result_hash: IChecksum256
coopname: IName
@@ -168,7 +172,10 @@ export interface IClaim {
type: IName
status: IName
created_at: ITimePointSec
amount: IAsset
author_amount: IAsset
creator_amount: IAsset
capitalist_amount: IAsset
total_amount: IAsset
claim_statement: IDocument
approved_statement: IDocument
authorization: IDocument
@@ -212,21 +219,40 @@ export interface IContributor {
approved_agreement: IDocument
authorization: IDocument
invested: IAsset
convert_percent: IUint64
contributed_hours: IUint64
rate_per_hour: IAsset
spend: IAsset
convert_percent: IUint64
for_convert: IAsset
available: IAsset
withdrawed: IAsset
converted: IAsset
expensed: IAsset
returned: IAsset
claimed: IAsset
share_balance: IAsset
pending_rewards: IAsset
reward_per_share_last: IInt64
}
export interface IConvert {
id: IUint64
project_hash: IChecksum256
result_hash: IChecksum256
convert_hash: IChecksum256
coopname: IName
username: IName
status: IName
convert_amount: IAsset
convert_statement: IDocument
created_at: ITimePointSec
}
export interface ICreateclaim {
coopname: IName
application: IName
username: IName
result_hash: IChecksum256
}
export interface ICreatecmmt {
coopname: IName
application: IName
@@ -237,6 +263,15 @@ export interface ICreatecmmt {
contribution_statement: IDocument
}
export interface ICreatecnvrt {
coopname: IName
application: IName
username: IName
result_hash: IChecksum256
convert_hash: IChecksum256
convert_statement: IDocument
}
export interface ICreateexpnse {
coopname: IName
application: IName
@@ -284,8 +319,7 @@ export interface ICreatewthd1 {
username: IName
result_hash: IChecksum256
withdraw_hash: IChecksum256
commit_hashes: IChecksum256[]
contribution_statement: IDocument
amount: IAsset
return_statement: IDocument
}
@@ -399,14 +433,6 @@ export interface IInvest {
approved_statement: IDocument
}
export interface IParticipant {
username: IName
coopname: IName
pending_rewards: IAsset
returned_rewards: IAsset
reward_per_share_last: IInt64
}
export interface IProgramWithdraw {
id: IUint64
coopname: IName
@@ -441,9 +467,11 @@ export interface IProject {
spend: IAsset
generated: IAsset
converted: IAsset
claimed: IAsset
withdrawed: IAsset
parent_distribution_ratio: IFloat64
membership_cumulative_reward_per_share: IInt64
membership_total_shares: IAsset
total_share_balance: IAsset
membership_funded: IAsset
membership_available: IAsset
membership_distributed: IAsset
@@ -489,14 +517,15 @@ export interface IRegcontrib {
export interface IResactor {
id: IUint64
project_hash: IChecksum256
result_hash: IChecksum256
username: IName
available: IAsset
for_convert: IAsset
spend: IAsset
authors_shares: IUint64
reward_per_share_last_authors: IInt64
creators_shares: IUint64
reward_per_share_last_creators: IInt64
participants_shares: IUint64
reward_per_share_last_participants: IInt64
creators_bonus_shares: IUint64
contributed_hours: IUint64
}
export interface IResult {
@@ -508,22 +537,24 @@ export interface IResult {
created_at: ITimePointSec
expired_at: ITimePointSec
authors_shares: IUint64
total_creators_bonus_shares: IUint64
authors_count: IUint64
commits_count: IUint64
allocated: IAsset
available: IAsset
spend: IAsset
expensed: IAsset
withdrawed: IAsset
creators_amount: IAsset
generated_amount: IAsset
creators_bonus: IAsset
authors_bonus: IAsset
generated_amount: IAsset
participants_bonus: IAsset
capitalists_bonus: IAsset
total_amount: IAsset
participants_bonus_remain: IAsset
authors_cumulative_reward_per_share: IInt64
creators_cumulative_reward_per_share: IInt64
participants_cumulative_reward_per_share: IInt64
authors_bonus_remain: IAsset
creators_amount_remain: IAsset
creators_bonus_remain: IAsset
capitalists_bonus_remain: IAsset
}
export interface IResultAuthor {
@@ -542,7 +573,6 @@ export interface IResultWithdraw {
withdraw_hash: IChecksum256
username: IName
status: IName
commit_hashes: IChecksum256[]
amount: IAsset
contribution_statement: IDocument
return_statement: IDocument
@@ -557,7 +587,7 @@ export interface ISetact1 {
coopname: IName
application: IName
username: IName
claim_hash: IChecksum256
commit_hash: IChecksum256
act: IDocument
}
@@ -565,7 +595,7 @@ export interface ISetact2 {
coopname: IName
application: IName
username: IName
result_hash: IChecksum256
commit_hash: IChecksum256
act: IDocument
}
@@ -575,14 +605,6 @@ export interface IStartdistrbn {
result_hash: IChecksum256
}
export interface IUpdatecapitl {
coopname: IName
application: IName
username: IName
result_hash: IChecksum256
claim_hash: IChecksum256
}
export interface IWthdrcallbck {
coopname: IName
callback_type: IName
+7 -16
View File
@@ -163,22 +163,6 @@ export interface ICapauthinvst {
meta: string
}
export interface ICapauthwthdc {
coopname: IName
username: IName
withdraw_id: IUint64
statement: IDocument
meta: string
}
export interface ICapauthwthdr {
coopname: IName
username: IName
withdraw_id: IUint64
statement: IDocument
meta: string
}
export interface ICapregcontr {
coopname: IName
username: IName
@@ -461,6 +445,13 @@ export interface IOnewallet {
initial: IAsset$
}
export interface IOpenprogwall {
coopname: IName
username: IName
program_type: IName
agreement_id: IUint64
}
export interface IParticipant {
username: IName
created_at: ITimePointSec
@@ -0,0 +1,15 @@
import * as Permissions from '../../../common/permissions'
import type * as Capital from '../../../interfaces/capital'
import { Actors } from '../../../common'
export const authorizations = [{ permissions: [Permissions.active], actor: Actors._chairman }] as const
/**
* Имя действия
*/
export const actionName = 'approvecnvrt'
/**
* @interface
*/
export type IApproveConvert = Capital.IApprovecnvrt
@@ -0,0 +1,15 @@
import * as Permissions from '../../../common/permissions'
import type * as Capital from '../../../interfaces/capital'
import { Actors } from '../../../common'
export const authorizations = [{ permissions: [Permissions.active], actor: Actors._chairman }] as const
/**
* Имя действия
*/
export const actionName = 'createclaim'
/**
* @interface
*/
export type ICreateClaim = Capital.ICreateclaim
@@ -0,0 +1,15 @@
import * as Permissions from '../../../common/permissions'
import type * as Capital from '../../../interfaces/capital'
import { Actors } from '../../../common'
export const authorizations = [{ permissions: [Permissions.active], actor: Actors._chairman }] as const
/**
* Имя действия
*/
export const actionName = 'createcnvrt'
/**
* @interface
*/
export type ICreateConvert = Capital.ICreatecnvrt
@@ -36,3 +36,7 @@ export * as StartDistribution from './startDistribution'
export * as WithdrawResult from './withdrawResult'
export * as WithdrawProject from './withdrawProject'
export * as WithdrawProgram from './withdrawProgram'
export * as CreateConvert from './createConvert'
export * as CreateClaim from './createClaim'
export * as ApproveConvert from './approveConvert'
+74 -52
View File
@@ -30,7 +30,8 @@ export interface IApproveclaim {
coopname: IName
application: IName
approver: IName
claim_hash: IChecksum256
username: IName
result_hash: IChecksum256
approved_statement: IDocument
}
@@ -42,6 +43,14 @@ export interface IApprovecmmt {
approved_statement: IDocument
}
export interface IApprovecnvrt {
coopname: IName
application: IName
approver: IName
convert_hash: IChecksum256
approved_statement: IDocument
}
export interface IApproveexpns {
coopname: IName
application: IName
@@ -72,7 +81,6 @@ export interface IApprovewthd1 {
application: IName
approver: IName
withdraw_hash: IChecksum256
approved_contribution_statement: IDocument
approved_return_statement: IDocument
}
@@ -99,11 +107,6 @@ export interface IAuthor {
shares: IUint64
}
export interface IAuthwithdrw1 {
coopname: IName
withdraw_hash: IChecksum256
}
export interface ICapauthclaim {
coopname: IName
claim_id: IUint64
@@ -128,6 +131,12 @@ export interface ICapauthinvst {
authorization: IDocument
}
export interface ICapauthwthd1 {
coopname: IName
withdraw_id: IUint64
authorization: IDocument
}
export interface ICapauthwthd2 {
coopname: IName
withdraw_id: IUint64
@@ -140,16 +149,12 @@ export interface ICapauthwthd3 {
authorization: IDocument
}
export interface ICapauthwthdc {
export interface ICapitalist {
username: IName
coopname: IName
withdraw_id: IUint64
authorization: IDocument
}
export interface ICapauthwthdr {
coopname: IName
withdraw_id: IUint64
authorization: IDocument
pending_rewards: IAsset
returned_rewards: IAsset
reward_per_share_last: IInt64
}
export interface ICapregcontr {
@@ -160,7 +165,6 @@ export interface ICapregcontr {
export interface IClaim {
id: IUint64
claim_hash: IChecksum256
project_hash: IChecksum256
result_hash: IChecksum256
coopname: IName
@@ -168,7 +172,10 @@ export interface IClaim {
type: IName
status: IName
created_at: ITimePointSec
amount: IAsset
author_amount: IAsset
creator_amount: IAsset
capitalist_amount: IAsset
total_amount: IAsset
claim_statement: IDocument
approved_statement: IDocument
authorization: IDocument
@@ -212,21 +219,40 @@ export interface IContributor {
approved_agreement: IDocument
authorization: IDocument
invested: IAsset
convert_percent: IUint64
contributed_hours: IUint64
rate_per_hour: IAsset
spend: IAsset
convert_percent: IUint64
for_convert: IAsset
available: IAsset
withdrawed: IAsset
converted: IAsset
expensed: IAsset
returned: IAsset
claimed: IAsset
share_balance: IAsset
pending_rewards: IAsset
reward_per_share_last: IInt64
}
export interface IConvert {
id: IUint64
project_hash: IChecksum256
result_hash: IChecksum256
convert_hash: IChecksum256
coopname: IName
username: IName
status: IName
convert_amount: IAsset
convert_statement: IDocument
created_at: ITimePointSec
}
export interface ICreateclaim {
coopname: IName
application: IName
username: IName
result_hash: IChecksum256
}
export interface ICreatecmmt {
coopname: IName
application: IName
@@ -237,6 +263,15 @@ export interface ICreatecmmt {
contribution_statement: IDocument
}
export interface ICreatecnvrt {
coopname: IName
application: IName
username: IName
result_hash: IChecksum256
convert_hash: IChecksum256
convert_statement: IDocument
}
export interface ICreateexpnse {
coopname: IName
application: IName
@@ -284,8 +319,7 @@ export interface ICreatewthd1 {
username: IName
result_hash: IChecksum256
withdraw_hash: IChecksum256
commit_hashes: IChecksum256[]
contribution_statement: IDocument
amount: IAsset
return_statement: IDocument
}
@@ -399,14 +433,6 @@ export interface IInvest {
approved_statement: IDocument
}
export interface IParticipant {
username: IName
coopname: IName
pending_rewards: IAsset
returned_rewards: IAsset
reward_per_share_last: IInt64
}
export interface IProgramWithdraw {
id: IUint64
coopname: IName
@@ -441,9 +467,11 @@ export interface IProject {
spend: IAsset
generated: IAsset
converted: IAsset
claimed: IAsset
withdrawed: IAsset
parent_distribution_ratio: IFloat64
membership_cumulative_reward_per_share: IInt64
membership_total_shares: IAsset
total_share_balance: IAsset
membership_funded: IAsset
membership_available: IAsset
membership_distributed: IAsset
@@ -489,14 +517,15 @@ export interface IRegcontrib {
export interface IResactor {
id: IUint64
project_hash: IChecksum256
result_hash: IChecksum256
username: IName
available: IAsset
for_convert: IAsset
spend: IAsset
authors_shares: IUint64
reward_per_share_last_authors: IInt64
creators_shares: IUint64
reward_per_share_last_creators: IInt64
participants_shares: IUint64
reward_per_share_last_participants: IInt64
creators_bonus_shares: IUint64
contributed_hours: IUint64
}
export interface IResult {
@@ -508,22 +537,24 @@ export interface IResult {
created_at: ITimePointSec
expired_at: ITimePointSec
authors_shares: IUint64
total_creators_bonus_shares: IUint64
authors_count: IUint64
commits_count: IUint64
allocated: IAsset
available: IAsset
spend: IAsset
expensed: IAsset
withdrawed: IAsset
creators_amount: IAsset
generated_amount: IAsset
creators_bonus: IAsset
authors_bonus: IAsset
generated_amount: IAsset
participants_bonus: IAsset
capitalists_bonus: IAsset
total_amount: IAsset
participants_bonus_remain: IAsset
authors_cumulative_reward_per_share: IInt64
creators_cumulative_reward_per_share: IInt64
participants_cumulative_reward_per_share: IInt64
authors_bonus_remain: IAsset
creators_amount_remain: IAsset
creators_bonus_remain: IAsset
capitalists_bonus_remain: IAsset
}
export interface IResultAuthor {
@@ -542,7 +573,6 @@ export interface IResultWithdraw {
withdraw_hash: IChecksum256
username: IName
status: IName
commit_hashes: IChecksum256[]
amount: IAsset
contribution_statement: IDocument
return_statement: IDocument
@@ -575,14 +605,6 @@ export interface IStartdistrbn {
result_hash: IChecksum256
}
export interface IUpdatecapitl {
coopname: IName
application: IName
username: IName
result_hash: IChecksum256
claim_hash: IChecksum256
}
export interface IWthdrcallbck {
coopname: IName
callback_type: IName
+7 -16
View File
@@ -163,22 +163,6 @@ export interface ICapauthinvst {
meta: string
}
export interface ICapauthwthdc {
coopname: IName
username: IName
withdraw_id: IUint64
statement: IDocument
meta: string
}
export interface ICapauthwthdr {
coopname: IName
username: IName
withdraw_id: IUint64
statement: IDocument
meta: string
}
export interface ICapregcontr {
coopname: IName
username: IName
@@ -461,6 +445,13 @@ export interface IOnewallet {
initial: IAsset
}
export interface IOpenprogwall {
coopname: IName
username: IName
program_type: IName
agreement_id: IUint64
}
export interface IParticipant {
username: IName
created_at: ITimePointSec