---
title: "Klucz prywatny nie wystarcza: kto może odebrać token RWA"
author: Mariusz Szyma
date: 2026-09-08
lang: pl
canonical: https://szyma.co/blog/rwa/kto-moze-zabrac-token/
series: "RWA: Past, Present and Future"
series_part: 5/13
series_url: https://szyma.co/blog/rwa/
data_as_of: 4–5 IX 2026
---

# Klucz prywatny nie wystarcza: kto może odebrać token RWA

Najmocniejsze uprawnienie w kontrakcie BUIDL, funkcja `setTarget` podmieniająca całą implementację, należało 4 września 2026 do jednego konta zewnętrznego, bez wielopodpisu i bez timelocka. Produkt o rząd wielkości mniejszy, OUSG od Ondo, rozłożył uprawnienia na trzy struktury wielopodpisowe o progach 4 z 7, 3 z 5 oraz 1 z 9. Jakość zarządzania uprawnieniami administracyjnymi w permissioned RWA jest odwrotnie proporcjonalna do wielkości emitenta.

Wszystkie odczyty on-chain w tym tekście pochodzą z 4 września 2026, przez publiczne endpointy `eth.blockscout.com` (Ethereum mainnet) i `horizon.stellar.org` (Stellar). Adresy kontraktów podaję, żeby dało się je powtórzyć.

## Backdoor nie jest luką w tych produktach, jest wymogiem

W permissioned RWA klucz prywatny nie daje kontroli nad saldem: potrzebny jest klucz oraz zgoda emitenta zapisana w rejestrze on-chain. To wiadomo z dokumentacji. Z dokumentacji nie wiadomo natomiast tego, co da się odczytać z kodu, i temu poświęcony jest ten tekst.

Zwykły ERC-20 ma jedną regułę transferu: saldo wystarcza, żeby je wysłać. Papier wartościowy takiej reguły mieć nie może, bo prawo nakłada na jego obrót pięć warunków: kto może posiadać, kiedy może przenieść, ile może posiadać, co się dzieje po nakazie sądowym, kto to nadzoruje.

Ten ostatni punkt jest najbardziej niewygodny. Transfer agent, czyli podmiot prowadzący rejestr posiadaczy udziałów funduszu (w tradycyjnym świecie bazę danych, a w RWA smart contract), ma prawny obowiązek wykonywania nakazów sądowych i korygowania błędów rejestru. Transfer agent zarejestrowany w SEC, który nie potrafi technicznie przenieść udziałów na podstawie nakazu, nie może wykonywać swojej funkcji. Stąd wniosek, który brzmi jak zarzut, a jest opisem konstrukcji: **produkt zgodny z prawem musi mieć backdoora.** Nie „może mieć". Musi.

Dlatego pytanie „czy ten produkt ma admin keys" jest źle postawione, bo odpowiedź zawsze brzmi „tak". Właściwe pytanie ma trzy części: jak wąsko zdefiniowano te uprawnienia, kto je trzyma, czy da się zweryfikować, że ich nie użyto.

## `seize` to sześć linijek kodu i jedna rola

BUIDL, tokenizowany fundusz BlackRocka z rejestrem udziałów prowadzonym on-chain przez Securitize jako transfer agenta, działa na własnościowej architekturze DS Protocol firmy Securitize. Nie jest to żaden EIP; kod ma nagłówek `SPDX-License-Identifier: UNLICENSED`, ale jest w pełni zweryfikowany na łańcuchu i można go przeczytać.

Funkcja przymusowego przeniesienia (*forced transfer*, czyli przeniesienie tokenów z adresu A na adres B bez zgody posiadacza A) nazywa się tu `seize` i wygląda tak:

```solidity
function seize(address _from, address _to, uint256 _value, string memory _reason)
    public virtual override onlyTransferAgentOrAbove {
    TokenLibrary.seize(tokenData, getCommonServices(), _from, _to, _value);
    emit Seize(_from, _to, _value, _reason);
    emit Transfer(_from, _to, _value);
    checkWalletsForList(_from, _to);
}
```

W tych sześciu linijkach istotne są trzy rzeczy.

Modyfikator to `onlyTransferAgentOrAbove`, nie `onlyMaster`. W DS Protocol role są czterostopniowe: MASTER (1), ISSUER (2), EXCHANGE (4), TRANSFER_AGENT (8). **Do przejęcia tokenów wystarcza druga rola od dołu.** Rolę TRANSFER_AGENT na kontraktcie BUIDL mają dziś dwa podmioty (odczyt `getRole()` na Trust Service `0x3a68756d0335e75c909ba1e8fefc1d4832c36c60`, 4 września 2026): konto zewnętrzne `0xA9994621F1c3EE59846Df756488229E8efDCB8bf` i kontrakt `TokenReallocator` `0xf33675685C8Ee774c7f5655C93AfEdC7B9818EcD`. Do tego konto MASTER.

Pole `_reason` przyjmuje dowolny string. Nie ma odwołania do hashu dokumentu, do rejestru nakazów, do żadnej weryfikowalnej podstawy. Uzasadnienie przejęcia udziałów jest polem tekstowym.

Operacji nie da się ukryć. Obok standardowego `Transfer` emitowane jest osobne zdarzenie `Seize`, więc każde użycie jest widoczne w indeksach natychmiast. To ważne i pozytywne.

Odpowiednik clawbacku, czyli odebranie tokenów bez przenoszenia ich na wskazany adres, to w BUIDL `burn` wywołany na cudzym adresie, z modyfikatorem `onlyIssuerOrTransferAgentOrAbove`. Krąg uprawnionych jest tu szerszy niż dla `seize`: rola ISSUER wystarcza do palenia z dowolnego adresu, ale nie do przymusowego przeniesienia. Rolę ISSUER ma dziś 2 konta zewnętrzne i 6 kontraktów systemowych (odczyt on-chain, 4 września 2026), łącznie osiem uprawnionych podmiotów.

## Najgroźniejsza funkcja nie nazywa się `seize`, a `setTarget`

Proxy BUIDL (`0x7712c34205737192402172409a8F7ccef8aA2AEc`) to nie standardowy wzorzec OpenZeppelin. To własny, czterdziestolinijkowy kontrakt. Jego istotna część:

```solidity
function setTarget(address _target) public onlyOwner {
    target = _target;
    emit ProxyTargetSet(_target);
}
```

Czego tu nie ma, a w standardowych rozwiązaniach jest: timelocka (zmiana wchodzi natychmiast), rozdzielenia admina proxy od właściciela logiki, wielopodpisu na poziomie kontraktu. Jedna zmienna, jedno wywołanie, cała implementacja podmieniona.

Odczyt `owner()` na tym adresie zwraca `0xE01605f6b6dc593b7d2917F4a0940dB2A625b09e`. Typ adresu: **konto zewnętrzne (EOA), nie kontrakt, nie multisig, nie Safe.** Ten sam adres ma rolę MASTER w Trust Service, bo `getRole()` zwraca `1` (odczyt on-chain, 4 września 2026).

Jeden klucz prywatny może zatem w jednej transakcji podmienić całą implementację kontraktu i jednocześnie trzyma najwyższą rolę administracyjną w systemie ról. Wszystkie odpowiedzi na pytanie „co ten kontrakt potrafi" są wobec tego tymczasowe, bo nowa implementacja może potrafić cokolwiek.

Uwaga metodologiczna: rola w kontraktcie nie mówi, kto trzyma klucz. Za adresem EOA może stać HSM z proceduralnym wielopodpisem po stronie operacyjnej Securitize i prawdopodobnie tak jest, ale on-chain tego nie widać. Multisig widać; procedura wewnętrzna nie.

Dobra praktyka jest w historii tego kontraktu widoczna: wdrożenie nastąpiło w bloku 19 343 277 (2024-03-01 22:20 UTC), a deployer zrzekł się roli MASTER 22 minuty później, w bloku 19 343 383, przekazując ją docelowemu adresowi.

## Drugi produkt nie ma tej funkcji w kodzie w ogóle

OUSG od Ondo to kontrakt `CashKYCSenderReceiver` (`0x1CEB44b6E515aBf009E0CCb6ddaFD723886cf3Ff`), czyli minimalne rozszerzenie OpenZeppelin z hookiem sprawdzającym KYC dla nadawcy, odbiorcy oraz wywołującego transakcję. Pełny zestaw funkcji mutujących odczytany z ABI (4 września 2026) to: `approve`, `burn(uint256)`, `burn(address,uint256)`, `burnFrom`, `decreaseAllowance`, `grantRole`, `increaseAllowance`, `initialize`, `mint`, `pause`, `renounceRole`, `revokeRole`, `setKYCRegistry`, `setKYCRequirementGroup`, `transfer`, `transferFrom`, `unpause`.

Czego na tej liście nie ma: `seize`, `forcedTransfer`, `freeze`, `setAddressFrozen`, `recoveryAddress`. **Kontrakt OUSG nie potrafi przenieść tokenów posiadacza na inny adres.** W ogóle, nie ma takiej funkcji w kodzie.

Funkcja `burn(address, uint256)`, czyli palenie z cudzego adresu, istnieje, ale jest chroniona rolą `BURNER_ROLE`, której nigdy nikomu nie nadano. Weryfikacja dwiema metodami: skan wszystkich zdarzeń `RoleGranted` od bloku wdrożenia (16 234 210) do bieżącego nie pokazuje ani jednego nadania tej roli, a `hasRole(BURNER_ROLE, addr)` zwraca `false` dla wszystkich adresów, które kiedykolwiek dostały jakąkolwiek rolę (odczyt on-chain, 4 września 2026).

To daje trzeci stan, którego większość analiz nie zna. Zwykle mówi się „ma uprawnienie" albo „nie ma". W praktyce najczęstszy jest stan pośredni: funkcja jest, uprawnionego nie ma, a odległość do stanu trzeciego mierzy się liczbą transakcji i podpisów.

![Funkcji nie ma w kodzie · funkcja jest, brak uprawnionego · funkcja jest, są uprawnieni. Przy każdym przejściu liczba transakcji i podpisów, które je wykonują.](https://szyma.co/blog/img/trzy-poziomy.3b728c01.webp)

Dla OUSG przejście z drugiego stanu do trzeciego to jedno wywołanie `grantRole` przez Safe o progu 4 z 7. Dla BUIDL nie ma żadnego przejścia, bo uprawnieni są już na miejscu.

## Trzy multisigi o trzech progach ma średni emitent, nie największy

Uprawnienia OUSG rozłożono na trzy osobne struktury wielopodpisowe o trzech różnych progach (weryfikacja `getThreshold()` i `getOwners()`, 4 września 2026):

| Zakres | Struktura | Próg |
|---|---|---|
| administracja tokena (`DEFAULT_ADMIN`, `MINTER`, `KYC_CONFIGURER`) | Safe `0xaed4caf2e535d964165b4392342f71bac77e8367` | 4 z 7 |
| rejestr tożsamości `OndoIDRegistryView` `0x56a5d911052323d688c731d516530878557463e7` | Safe `0x5ae21c99fc5f1584d8cb09a298cffd92b5d178ef` | 3 z 5 |
| pauza awaryjna (`PAUSER`) | Safe `0x2e55b738f5969eea10fb67e326bee5e2fa15a2cc` | 1 z 9 |

Ten ostatni próg wygląda jak błąd, a jest projektem: dziewięciu właścicieli, jeden podpis wystarcza, każda z dziewięciu osób może samodzielnie zatrzymać cały token. Uprawnienia destrukcyjne dostały wysoki próg, uprawnienia obronne niski. Do tego rejestr tożsamości: deployer nadał sobie rolę w bloku 22 141 359, przekazał ją multisigowi w bloku 22 141 361, a zrzekł się jej w bloku 22 141 362, czyli w trzech blokach komplet.

Dźwignia w OUSG leży nie w forced transfer, którego kontrakt nie ma, ale w rejestrze KYC. Hook `_beforeTokenTransfer` wymaga statusu KYC dla nadawcy, odbiorcy oraz wywołującego, więc **zarządca rejestru może skutecznie zablokować posiadacza, mimo braku funkcji freeze**: po usunięciu z rejestru jego `transfer` będzie revertował. Funkcja `setKYCRegistry` pozwala podmienić cały rejestr tożsamości pod tokenem; uprawnienie ma Safe 4 z 7. Freeze przez usunięcie z rejestru jest przy tym trudniejszy do wykrycia z zewnątrz niż jawna flaga `frozen`: nie ma zdarzenia „zamrożono adres X", jest zdarzenie usunięcia z rejestru, wyglądające jak rutynowa operacja compliance.

## Na Stellarze clawback wykonuje jeden z dziesięciu sygnatariuszy

BENJI Franklin Templetona nie ma smart contractu z compliance. Ma flagi na koncie emitenta, czyli reguły egzekwowane przez protokół sieci, nie przez kod emitenta. Konto emitenta to `GBHNGLLIE3KWGKCHIKMHJ5HVZHYIK7WTBE4QF5PLAKL4CJGSEU7HZIW5`, weryfikowalne przez `home_domain` = `www.franklintempleton.com` (odczyt Horizon, 4 września 2026). Wszystkie trzy flagi kontrolne są włączone: `auth_required` (nikt nie trzyma BENJI bez jawnej autoryzacji), `auth_revocable` (autoryzację można odebrać, czyli zamrozić saldo), `auth_clawback_enabled` (tokeny można odebrać z dowolnego konta). Czwarta, `auth_immutable`, jest na `false`, więc flagi wciąż można zmienić.

Model podpisów jest nietypowy. Master key konta ma wagę 0, czyli jest wyłączony i nie podpisze samodzielnie niczego. Sygnatariuszy o wadze 3 jest dziesięciu, o wadze 1 czterech, suma wag 34. Progi: `low = 2`, `med = 2`, `high = 6`.

Operacja `Clawback` podlega progowi medium. Skoro `med_threshold = 2`, a sygnatariusz wagi 3 sam przekracza ten próg, to **jeden z dziesięciu sygnatariuszy może samodzielnie odebrać BENJI z dowolnego konta albo je zdeautoryzować.** Zmiana samych reguł przez `SetOptions` (dodanie sygnatariusza, zmiana progów, zmiana flag) wymaga progu 6, więc dwóch sygnatariuszy wagi 3. Projekt jest świadomie asymetryczny: operacje w ramach reguł mają niski próg, zmiana reguł wysoki. Ta sama filozofia co progi 4 z 7 i 1 z 9 w OUSG, wyrażona w innym systemie.

Skuteczność allow-listy widać w liczbach: BENJI ma 1 357 autoryzowanych trustlinek i 953 nieautoryzowane (odczyt Horizon, 4 września 2026). Trustline to na Stellarze deklaracja konta, że chce trzymać dany asset, czyli 41% chętnych odrzucono na poziomie protokołu.

## Rodzaj uprawnienia różni się bardziej niż jego siła

![Trzy produkty, trzy modele władzy: kto może przejąć, odebrać, zamrozić, zmienić reguły, oraz jakiego typu podmiotem jest posiadacz każdego uprawnienia.](https://szyma.co/blog/img/uprawnienia-tabela.ae16660c.webp)

Te trzy modele różnią się nie stopniem, ale rodzajem:

| Wymiar | BUIDL (DS Protocol) | OUSG (ERC-20 + rejestr KYC) | BENJI (Stellar) |
|---|---|---|---|
| Przejęcie tokenów | `seize` → dowolny adres | brak funkcji w kodzie | `Clawback` → unicestwienie |
| Wycofanie tokenów | `burn`, 8 uprawnionych | `burn(address,…)`, 0 uprawnionych | `Clawback`, próg 2 (1 sygnatariusz wagi 3) |
| Zamrożenie salda | pośrednio (usunięcie z rejestru) | pośrednio (usunięcie z rejestru KYC) | wprost, `auth_revocable` |
| Pauza całego tokena | TRANSFER_AGENT lub wyżej | Safe 4 z 7 lub Safe 1 z 9 | brak globalnej pauzy |
| Zmiana reguł | `setTarget`, 1 EOA | ProxyAdmin `0xba80aa44cc25e85cc30359150dfb1c7d041cf6d5` → Safe 4 z 7 | `SetOptions`, próg 6 (2 sygnatariusze) |
| Timelock | brak | brak | brak |

`seize` przenosi tokeny na wskazany adres, więc token dalej istnieje i można go zwrócić. `Clawback` unicestwia, więc nie ma czego zwracać. Te dwie rzeczy bywają opisywane tym samym zwrotem „możliwość zamrożenia tokenów" i to jest nieprecyzyjne do bezużyteczności.

Drugi wynik jest mniej oczekiwany. **Największy produkt ma najsłabszą higienę kluczy, średni najlepszą.** BUIDL ma jeden EOA na upgrade i osiem podmiotów uprawnionych do palenia z cudzego adresu. OUSG ma trzy multisigi o trzech progach i zero uprawnionych do palenia. Powód jest strukturalny, nie kulturowy: BUIDL to fundusz działający na wyłączeniu Section 3(c)(7) z Investment Company Act, z transfer agentem zarejestrowanym w SEC, który ma obowiązki rejestrowe wymagające tych funkcji. Więcej uprawnień nie oznacza gorszego produktu, ale inne obowiązki. Oznacza też inny profil ryzyka.

Trzeci wynik: żadne z tych uprawnień nie jest audytowalne przed użyciem. Wszystkie trzy są audytowalne po. Nie ma timelocka w żadnym z tych produktów, więc użycie `seize` na danym adresie staje się widoczne dopiero po fakcie.

## Compliance jest w kontraktcie i kosztuje cztery razy więcej gazu

Parametry, które w tradycyjnym funduszu leżą w dokumencie ofertowym, w BUIDL leżą w kontraktcie `ComplianceConfigurationService` (`0x1dc378568cefd4596c5f9f9a14256d8250b56369`). Odczyt getterów, 4 września 2026:

| Parametr | Wartość | Znaczenie |
|---|---|---|
| `getTotalInvestorsLimit()` | 1 999 | maksymalna liczba inwestorów |
| `getTotalInvestorsCount()` | 89 | stan faktyczny, 4,5% limitu |
| `getUSAccreditedInvestorsCount()` | 32 | inwestorzy akredytowani z USA |
| `getForceAccredited()` / `getForceAccreditedUS()` | 1 / 1 | wszyscy muszą być akredytowani |
| `getUSLockPeriod()` / `getNonUSLockPeriod()` | 86 400 s (24 h) | lock-up, czyli minimalny czas między nabyciem i możliwością zbycia |
| `getBlockFlowbackEndTime()` | 1 703 980 800 (31 grudnia 2023) | data w przeszłości, blokada flowbacku wygasła |
| `getMaximumHoldingsPerInvestor()` | 0 | brak limitu górnego |

Limit 1 999 inwestorów jest wykorzystany w 4,5%, co przeczy narracji o „ograniczonej pojemności" tych funduszy. Lock-up wynosi 24 godziny, nie rok. To nie produkt zablokowany na długo, ale produkt zablokowany dla wąskiej grupy. Osobno: `cap()` zwraca `0`, czyli podaż nie ma limitu emisji, a `setCap` jest jednorazowy i przysługuje transfer agentowi.

Ta warstwa ma mierzalny koszt. Compliance BUIDL jest rozproszony na jedenaście osobnych kontraktów wywoływanych przy transferze, w tym `InvestorLockManager` (`0x0a65a40a4b2f64d3445a628abcfc8128625483a4`) i `ComplianceServiceRegulated` (`0x07a1ebfb9a9a421249ddc71bddb8860cc077e3a9`). Pomiar `gasUsed` dla `transfer(address,uint256)` na Ethereum mainnet, mediana z potwierdzonych transakcji (4 września 2026):

| Token | Architektura | `gasUsed` | n | Mnożnik |
|---|---|---|---|---|
| USDC | zwykły ERC-20 | 45 160 | 40 | 1,00× |
| OUSG | 1 kontrakt + 1 rejestr | 91 335 | 17 | 2,02× |
| BUIDL | 11 kontraktów DS Protocol | 183 672 | 46 | 4,07× |

Rozstrzał w BUIDL sięga od 178 569 do 1 139 537 jednostek, a górna wartość to transfer uruchamiający dodatkowe operacje rejestrowe. **Dwa razy więcej reguł to dwa razy więcej gazu**, czyli techniczny sufit dla produktów detalicznych na Ethereum mainnet.

## Zero użyć w dwa i pół roku nie jest dowodem bezpieczeństwa

Skan logów kontraktu BUIDL po `topic0` zdarzeń, od bloku wdrożenia (19 343 277) do 4 września 2026:

- `Seize` — 0
- `OmnibusSeize` — 0
- `OmnibusBurn` — 0
- `Pause` — 0, `Unpause` — 0
- `Burn` — 208
- `Issue` — ponad 1 000

Uprawnienie do przymusowego przeniesienia istnieje od 1 marca 2024 i nie zostało użyte ani razu; token nigdy nie był zatrzymany. Na OUSG rola do palenia z cudzego adresu nigdy nie została nikomu nadana. Na BENJI nie znalazłem operacji `clawback`, ale to próbka 200 ostatnich operacji konta emitenta, pokrywająca około 7,5 godziny, więc **nie jest to dowód braku użycia w całej historii aktywa**.

Z 208 zdarzeń `Burn` na BUIDL nie da się odróżnić wykupu od konfiskaty. Oba emitują to samo zdarzenie z polem `_reason` wypełnianym dowolnym stringiem, a treści tych pól nie odczytano. Interpretacja „to niemal na pewno wykupy" jest uzasadniona mechaniką umorzenia w tym modelu, ale nie jest pomiarem.

Zero użyć nie jest dowodem bezpieczeństwa; jest dowodem, że dotąd nie użyto. To jednak jedyny dowód, jaki w tej sprawie istnieje, i pozwala oddzielić ryzyko potencjalne od zmaterializowanego. W tych trzech produktach ryzyko admin keys jest dziś potencjalne, a to sformułowanie jest uczciwsze niż obie skrajne narracje.

## Cztery sieci, ten sam backdoor, cztery różne implementacje

Wszystko powyżej opierało się na odczycie z Ethereum. To była największa dziura w tym tekście, bo BUIDL istnieje w wielu wdrożeniach, a każde jest osobnym kontraktem, nie kopią. Odczytałem więc uprawnienia BUIDL bezpośrednio z trzech kolejnych łańcuchów: Avalanche, Solany, Aptosa, 5 września 2026. Adresy wzięte z mapowania platform w CoinGecko, ale każdy zweryfikowany odczytem `symbol()`, `name()` albo metadanych na docelowej sieci. Adres z serwisu trzeciego nie jest jeszcze dowodem, że odczytywany kontrakt jest właściwy. Adres solanowy zgadza się także z komunikatem Securitize z 25 marca 2025 🟢.

Wynik jest jednoznaczny w jednej rzeczy: **odpowiednik funkcji `seize` istnieje na każdej sprawdzonej sieci.** Nigdzie nie znalazłem multisiga.

![BUIDL na czterech sieciach z dziewięciu: odpowiednik funkcji seize istnieje na każdej, multisiga nie ma na żadnej. Odczyt z łańcuchów, 4–5 września 2026.](https://szyma.co/blog/img/uprawnienia-multichain.649fc8a9.webp)

## Avalanche nie powtarza wzorca proxy z Ethereum

Token `0x53fc82f14f009009b440a706e31c9021e1196a2f`, proxy o długości 171 bajtów wskazujące na implementację `0xf93667d01c7675e2667ee392aa69104df79c4ad0` (19 063 bajty). Skan bytecode implementacji na selektory funkcji daje obecne: `seize(address,address,uint256,string)`, `omnibusSeize(...)`, `burn(address,uint256,string)`, `omnibusBurn(...)`, `pause()`, `unpause()`, `transferOwnership(address)`, `setDSService(uint256,address)`, `preTransferCheck(address,address,uint256)`. Nieobecne: `forcedTransfer`, `freeze`, `unfreeze`, `mint(address,uint256)` oraz `setTarget(address)`. Wdrożenie na Avalanche nie powtarza więc wzorca proxy z Ethereum, opisanego wyżej jako najgroźniejszy. Tu jest standardowe ERC-1967 z pustym slotem admina, a ścieżka aktualizacji prowadzi przez `upgradeToAndCall` w samej implementacji, czyli UUPS.

Uprawnienie właścicielskie: `owner()` zwraca `0xe01605f6b6dc593b7d2917f4a0940db2a625b09e`, a `eth_getCode` na tym adresie zwraca pustkę, czyli to konto zewnętrzne, nie kontrakt, nie multisig. `isPaused()` zwraca 0. Z odczytu bloku wdrożenia wynika, że kontrakt stoi na łańcuchu od 4 listopada 2024, 14:12 UTC, czyli dziewięć dni przed komunikatem o ekspansji z 13 listopada 2024 🟢.

## Na Solanie uprawnienie trzyma program, a nie klucz prywatny

Mint `GyWgeqpy5GueU2YbkE8xqUeVEokCMMCEeUrfbtMw6phr` działa na programie Token-2022. Rozszerzenie `permanentDelegate` jest włączone, a delegatem jest `APm3MWbXfMMKAWgsDVnxcAGbLjvRxubPu1A8a5SA2kbJ`. Permanent delegate może przenieść albo spalić tokeny z dowolnego konta posiadacza bez jego udziału i, inaczej niż zwykłe zezwolenie, nie da się go odwołać. Ten sam adres jest jednocześnie `mintAuthority`, `freezeAuthority`, `mintCloseAuthority`, authority `transferHook` i authority metadanych. Pięć uprawnień, jeden adres.

Tu jednak zaczyna się rzecz, której nie przewidziałem: **`APm3MW…` nie jest kluczem prywatnym.** Konto ma 73 bajty danych i należy do programu `7tXjmbkZVY3Gmg9kDBebcNXT1yC5pyoxxXVLwdbv9tvP`, czyli jest kontem sterowanym programowo. Nikt nie „ma klucza do seize" na Solanie w tym sensie, w jakim ma go na Ethereum. Struktura jest lepsza niż na Ethereum, ale tylko o jeden poziom. Program-kontroler został wdrożony 14 marca 2025, a program transfer hooka (`FsE8mCJyvgMzqJbfHbJQm3iuf3cRZC6n2vZi1Q8rQCy2`) 26 sierpnia 2025, i upgrade authority obu jest ten sam adres `8d36iv2YUD8yDChuVZchx1NqE4qkDWCAEgsUEEUqzbB6`, który należy do System Program i ma zero bajtów danych, czyli jest zwykłym kontem-kluczem. Kto go kontroluje, nie przejmie tokenów jednym podpisem, ale może podmienić kod programu, który to robi. To ta sama koncentracja co na Ethereum, przesunięta o jeden krok w tył.

## Na Aptosie token nie jest domyślnie zbywalny

Obiekt fungible asset `0x50038be55be5b964cfa32cf128b5cf05f123959f286b4cc02b86cafd48945f89` ma metadane „BlackRock BUIDL", symbol BUIDL, 6 miejsc po przecinku. Uprawnienia są tu wyrażone w sposób, którego nie ma na żadnym EVM: obiekt ma zasób `0x1::fungible_asset::Untransferable`, co wyłącza zwykły transfer na poziomie samego standardu. Token staje się zbywalny wyłącznie przez funkcje dyspozytorskie emitenta. Do tego dochodzi `dispatchable_fungible_asset::TransferRefStore`, czyli moduł Securitize trzyma referencję pozwalającą ruszyć zawartość dowolnego magazynu, oraz `DispatchFunctionStore` z własnymi hookami wypłaty i wpłaty, czyli kontrolą compliance przy każdym transferze.

Funkcja jest w Move nazwana dokładnie tak samo jak w Solidity: `ds_token::seize(&signer, address, address, u64, String)`, funkcja typu entry, z tym samym dowolnym stringiem jako uzasadnieniem. Obok niej `ds_token::burn(&signer, address, u64, String)`, `set_pause`, `transfer_from`, `set_cap`, `set_features`, `set_metadata`. Cały DS Protocol został przeniesiony na Move jako dziewięć modułów: `ds_token`, `lock_manager`, `token_issuer`, `bulk_operator`, `trust_service`, `wallet_manager`, `registry_service`, `wallet_registrar`, `compliance_service`. `is_paused` zwraca `false`.

Kontrola: moduły stoją na koncie `0x4de5876d8a8e2be7af6af9f3ca94d9e4fafb24b5f4a5848078d8eb08f08e808a`, które jest kontem-obiektem, ma zasób `ObjectCore` i `sequence_number` równy 0, czyli samo nigdy nie podpisało transakcji. Właścicielem tego obiektu jest `0x91840004a08dbf21c9ad96ee1c8ef40a6aca24fba6ff23b6ded5a8d17028977b`, konto z jednym zasobem `Account`, bez zasobu multisig. Warstwa pośrednia jest, rozproszenia kontroli nie ma.

## Ethereum nie jest największym wdrożeniem BUIDL

Podaże BUIDL na sprawdzonych sieciach, w jednostkach tokena: Solana 977 902 117,97; Avalanche 564 231 692,75; Ethereum 211 920 742,07 (odczyt 4 września 2026); Aptos 161 340 739,89. Razem 1 915 395 292,68 na czterech sieciach z dziewięciu. **Solana jest od Ethereum 4,6 razy większa.** Każde zdanie o tym produkcie oparte wyłącznie na odczycie z Ethereum opisuje jedenaście procent jego podaży. Włącznie z moimi wcześniejszymi.

Czego nie ustaliłem. Czy uprawnienie przymusowe zostało kiedykolwiek użyte na Avalanche, Solanie albo Aptosie, nie wiem. Na Avalanche publiczny węzeł limituje `eth_getLogs` do 2048 bloków, a od wdrożenia minęło 41 884 144 bloków, co daje 20 451 żądań na pełną historię; nie wykonałem tego. Na Solanie wymagałoby to skanu historii transakcji, na Aptosie indeksera, do którego nie miałem dostępu. Zero użyć jest potwierdzone wyłącznie dla Ethereum i wyłącznie na dzień 4 września 2026.

## Trzy pytania, których nie zadaje żaden materiał marketingowy

Klucz prywatny w permissioned RWA nie wystarcza i to jest cecha konstrukcji, nie usterka: bez `seize` transfer agent nie wykonałby nakazu sądowego, a bez allow-listy fundusz nie wszedłby na publiczny łańcuch. Odczyt kodu pokazuje jednak coś, czego z tej konstrukcji nie da się wyprowadzić: sposób trzymania tych uprawnień nie skaluje się z wielkością emitenta. Skaluje się z tym, kiedy produkt zbudowano i po co. BlackRock i Securitize dostali architekturę zaprojektowaną wokół obowiązków transfer agenta, z jednym EOA jako właścicielem proxy. Ondo, młodsza firma crypto-native bez tych obowiązków, zbudowała trzy multisigi i nie napisała funkcji przejęcia. Franklin Templeton oddał compliance protokołowi i wyłączył master key konta, ale pozostawił clawback jednemu podpisowi z dziesięciu.

Z tego wynikają trzy pytania, na które odpowiada łańcuch, a nie dek. Pierwsze dotyczy tego, kto może zmienić reguły: EOA, multisig, multisig z timelockiem. Drugie dotyczy tego, kto może ruszyć saldo posiadacza bez jego zgody, czyli czy funkcja istnieje, czy ma uprawnionego, ilu ich jest. Trzecie dotyczy tego, czy tych uprawnień użyto, czyli ile zdarzeń w jakim okresie. Trzecie jest najłatwiejsze i najczęściej pomijane, a pierwsze jest najważniejsze, bo unieważnia odpowiedź na drugie: **jeśli implementację można podmienić jedną transakcją, to „w kodzie nie ma `seize`" jest stanem, nie gwarancją.**

## Źródła

**Odczyty on-chain — 4 września 2026 (🟢 pierwotne)**

- Ethereum mainnet przez `eth.blockscout.com` (API v2 dla kodu źródłowego i ABI, `api/eth-rpc` dla `eth_call`, `eth_getStorageAt`, `eth_getLogs`)
- BUIDL proxy `0x7712c34205737192402172409a8F7ccef8aA2AEc` — pełny kod kontraktu `Proxy` (40 linii), `owner()`, `target()`, sloty 0 i 1
- BUIDL implementacja `0x603bB6909bE14F83282e03632280d91Be7Fb83B2` — `DSToken` v5, kod główny plus 36 plików zależnych (`ComplianceServiceRegulated`, `ServiceConsumer`, `IDSTrustService`, `TokenLibrary` i pozostałe)
- BUIDL Trust Service `0x3a68756d0335e75c909ba1e8fefc1d4832c36c60` — zdekodowane zdarzenia `DSTrustServiceRoleAdded` / `RoleRemoved` / `ProxyTargetSet` / `ProxyOwnerChanged` (20 zdarzeń, komplet), `getRole()` dla 11 adresów
- BUIDL `ComplianceConfigurationService` `0x1dc378568cefd4596c5f9f9a14256d8250b56369` — 40 getterów parametrów compliance; `ComplianceServiceRegulated` `0x07a1ebfb9a9a421249ddc71bddb8860cc077e3a9` — liczniki inwestorów
- BUIDL — rejestr usług przez `getDSService(uint256)` dla 13 identyfikatorów; skan `eth_getLogs` po `topic0` zdarzeń `Seize`, `OmnibusSeize`, `Burn`, `OmnibusBurn`, `Pause`, `Unpause`, `Issue` od bloku 19 343 277; daty bloków przez `eth_getBlockByNumber`
- OUSG proxy `0x1B19C19393e2d034D8Ff31ff34c81252FCBbee92` (slot EIP-1967 implementacji i admina), implementacja `0x1CEB44b6E515aBf009E0CCb6ddaFD723886cf3Ff` — pełny kod `CashKYCSenderReceiver` plus 22 pliki zależne
- OUSG — komplet zdarzeń `RoleGranted` (28) i `RoleRevoked` (22) od bloku 16 234 210; weryfikacja przez `hasRole()` dla 5 ról × 6 adresów; `ProxyAdmin` `0xba80aa44cc25e85cc30359150dfb1c7d041cf6d5` → `owner()`
- Safe `0xaed4caf2e535d964165b4392342f71bac77e8367` (`getThreshold() = 4`, 7 właścicieli), Safe `0x2e55b738f5969eea10fb67e326bee5e2fa15a2cc` (`getThreshold() = 1`, 9 właścicieli), Safe `0x5ae21c99fc5f1584d8cb09a298cffd92b5d178ef` (`getThreshold() = 3`, 5 właścicieli); `OndoIDRegistryView` `0x56a5d911052323d688c731d516530878557463e7` — ABI, zdarzenia ról, `hasRole()`
- Pomiar `gasUsed` dla `transfer(address,uint256)`: USDC `0xA0b86991…eB48` (n = 40), OUSG (n = 17), BUIDL (n = 46), przez `eth_getLogs` i `eth_getTransactionReceipt`
- Stellar przez `horizon.stellar.org`: `GET /accounts/GBHNGLLI…ZIW5` (`home_domain`, `flags`, `thresholds`, sygnatariusze z wagami), `GET /assets?asset_code=BENJI&limit=20`, `GET /accounts/{issuer}/operations?order=desc&limit=200`

**Dokumentacja i specyfikacje (🟢 pierwotne)**

- Kod źródłowy DS Protocol — odczytany z łańcucha; licencja `UNLICENSED`, brak publicznego repozytorium
- Stellar Developers — semantyka flag `auth_required`, `auth_revocable`, `auth_clawback_enabled`, `auth_immutable`; model wag i progów sygnatariuszy
- Securitize, komunikat prasowy o uruchomieniu BUIDL — role BlackRock Financial Management, BNY Mellon, Securitize, PwC; podstawa prawna Rule 506(c) i Section 3(c)(7)
- Stellar.org, case study Franklin Templeton — uzasadnienie wyboru sieci (kontrole na poziomie protokołu)

**Źródła wtórne (🟡)**

- Etherscan — liczba posiadaczy OUSG (53) na 13 sierpnia 2026
- Kaleido, *Understanding ERC-3643 Tokenization on Ethereum*; QuickNode Guides, *What is ERC-3643?* — architektura standardu i nazwy uprawnień administracyjnych, użyte wyłącznie do kontekstu porównawczego
- Coinpaprika, *BlackRock BUIDL Fund* — rejestracja spółki BVI 18 września 2023, start produktu 20 marca 2024

- Odczyt on-chain z 5 września 2026 🟢 — Avalanche C-Chain (`eth_call`, `eth_getCode`, `eth_getStorageAt` na slocie implementacji ERC-1967, skan selektorów w bytecode implementacji), Solana (`getAccountInfo` z parsowaniem rozszerzeń Token-2022, `getTokenSupply`, konta ProgramData obu programów), Aptos (`/accounts/{addr}/resources`, `/accounts/{addr}/modules`, `/view` dla `is_paused`). Surowe wyniki w pliku `onchain_multichain_buidl.json`
- CoinGecko, endpoint `/coins` 🟡 — mapowanie adresów kontraktu na dziewięć platform, stan na 5 września 2026. Użyte wyłącznie do znalezienia adresów; każdy adres zweryfikowany następnie odczytem z docelowej sieci
- Securitize/PR Newswire, komunikat o klasie udziałów na Solanie, 25 marca 2025 🟢 — adres tokena solanowego i opłata za zarządzanie 20 bps

**Źródła trzeciorzędne (🔴)**

- eco.com, deep dive'y BUIDL / OUSG / BENJI — parametry operacyjne i mechanika whitelisty; nie użyte do żadnej liczby dotyczącej uprawnień

## Zastrzeżenia

Cztery łańcuchy z dziewięciu, nie jeden, ale nie wszystkie. Pierwotnie ten tekst opierał się na odczycie z jednej sieci na produkt. Dla BUIDL domknąłem to do czterech: Ethereum (4 września 2026), Avalanche, Solana, Aptos (5 września 2026). Pozostają nieodczytane Arbitrum, Optimism, Polygon, BNB Chain i Tempo. Liczba sieci jest w źródłach sporna i nie zacieram tego: materiały do czerwca 2026 podają osiem (The Defiant, czerwiec 2025; spotedcrypto, czerwiec 2026), źródło z 3 sierpnia 2026 dziewięć, po dodaniu Tempo w lipcu 2026 (Coinpaprika); mapowanie platform CoinGecko z 5 września 2026 wylicza dziewięć wraz z Tempo. Dla OUSG odczytano wyłącznie Ethereum, dla BENJI wyłącznie Stellara, i tam nadal nie wiem, czy uprawnienia na pozostałych sieciach są takie same.

Rozbieżność, której nie należy zacierać. Odczyt `totalSupply` kontraktu BUIDL na Ethereum daje 211 920 742,07 tokena (4 września 2026), przy relacji 1 token = 1 udział o docelowej wartości 1 USD. Baza wiedzy, z której pochodzi ten tekst, opisuje BUIDL jako produkt rzędu 2,5 mld USD, ale bez podanej daty odczytu. Te liczby nie są sprzeczne: odczyt dotyczy jednej klasy udziałów na jednym łańcuchu z ośmiu, a nie całego funduszu. Podaję obie i nie uśredniam. Klasy BUIDL-I (`0x6a9DA2D710BB9B700acde7Cb81F10F1fF8C89041`) nie odczytano.

Czego nie ustalono. Czy za adresem `0xE01605f6b6dc593b7d2917F4a0940dB2A625b09e` stoi HSM z proceduralnym wielopodpisem, czy pojedynczy podpisujący, on-chain tego nie widać. Czy 208 zdarzeń `Burn` na BUIDL to wyłącznie wykupy, treści pól `_reason` nie odczytano. Czy `Clawback` był kiedykolwiek użyty na BENJI, próbka pokrywa 7,5 godziny, nie całą historię aktywa od 2021 roku. Czy limit 1 999 inwestorów wynika z progu 2 000 beneficial owners w Section 3(c)(7), liczba jest zbieżna, zależności nie zweryfikowano w dokumencie ofertowym funduszu.

Anomalia licznika. `getTotalInvestorsCount()` zwraca 89, `getUSAccreditedInvestorsCount()` 32, ale `getAccreditedInvestorsCount()` zwraca 91, więcej niż total. Nie ustalono, czy to inna definicja, błąd licznika, czy pozostałość historyczna. Odnotowuję jako anomalię, nie interpretuję.

Dane się starzeją. Role, progi multisigów i parametry compliance są stanem na 4 września 2026 i mogą zmienić się jedną transakcją. Rotacje roli ISSUER na BUIDL widać w łańcuchu co kilka miesięcy, ostatnią 1 kwietnia 2026. Każdą liczbę z tego tekstu da się odczytać ponownie pod podanym adresem.
