37 KiB
Security of Digital Legal Entity (DLE)
📋 Table of Contents
- Introduction
- Security Model
- Token-Based Access Control
- Smart Contract Security
- Wallet Hack Protection
- Web Application Security
- Module Management
- Audit and Monitoring
- Security Recommendations
- Attack Scenarios and Protection
Introduction
Digital Legal Entity (DLE) is built with a focus on security at all levels:
- 🔐 Access control through blockchain tokens
- 🛡️ Smart contract protection from hacking
- 🔒 Impossible to steal tokens even if wallet is hacked
- ⚖️ Management only through voting with quorum
Key Security Principles
- Security by default - all actions are prohibited until explicitly allowed
- Least privilege - everyone gets only necessary rights
- Transparency - all actions recorded on blockchain
- Immutability - impossible to forge history
- Collective control - critical operations only through voting
Security Model
Security Architecture
┌─────────────────────────────────────────────────────────────┐
│ DLE Protection Levels │
├─────────────────────────────────────────────────────────────┤
│ │
│ Level 1: Blockchain (Immutable Base) │
│ ┌───────────────────────────────────────────────────────┐ │
│ │ • DLE Smart Contract (audited, immutable) │ │
│ │ • Governance Tokens (ERC20Votes) │ │
│ │ • History of all operations on blockchain │ │
│ │ • Impossible to change rules without voting │ │
│ └───────────────────────────────────────────────────────┘ │
│ ↑ │
│ Level 2: Web Application (Backend) │
│ ┌───────────────────────────────────────────────────────┐ │
│ │ • Real-time token verification │ │
│ │ • Wallet authentication (SIWE) │ │
│ │ • Data encryption (AES-256) │ │
│ │ • Rate limiting and DDoS protection │ │
│ └───────────────────────────────────────────────────────┘ │
│ ↑ │
│ Level 3: Frontend (Vue.js) │
│ ┌───────────────────────────────────────────────────────┐ │
│ │ • Wallet connection │ │
│ │ • Transaction signing │ │
│ │ • XSS protection (DOMPurify) │ │
│ │ • CSRF tokens │ │
│ └───────────────────────────────────────────────────────┘ │
│ ↑ │
│ Level 4: User │
│ ┌───────────────────────────────────────────────────────┐ │
│ │ • Wallet private key (MetaMask, WalletConnect) │ │
│ │ • Confirmation of each operation │ │
│ └───────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
Threat Model
| Threat | Risk Level | Protection |
|---|---|---|
| Wallet hack | 🟡 Medium | Tokens cannot be transferred without voting |
| Web application hack | 🟢 Low | All rights verified on blockchain, management via blockchain explorers |
| Smart contract compromise | 🟢 Low | Audit, OpenZeppelin, immutability |
| DDoS attack | 🟡 Medium | Rate limiting, CDN, backup servers |
| Phishing | 🟠 High | User education, domain verification |
| Insider threat | 🟢 Low | All actions through voting |
⚠️ Critical: Web Application is Only an Interface
Key feature of DLE architecture:
┌─────────────────────────────────────────────────────────┐
│ Web Application (Interface) │
│ │
│ Frontend + Backend = CONVENIENCE of use │
│ • Beautiful UI │
│ • Convenient navigation │
│ • Quick access to functions │
│ │
│ ⚠️ Can be hacked/unavailable │
│ ✅ BUT! Business assets are protected │
└─────────────────────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────────────────┐
│ Blockchain (Real Power) │
│ │
│ Smart Contracts = REAL asset management │
│ • Governance tokens │
│ • Treasury with assets │
│ • Voting rules │
│ • History of all decisions │
│ │
│ 🔒 Protected by cryptography │
│ ✅ Works independently of web application │
└─────────────────────────────────────────────────────────┘
What happens when web application is hacked:
Web application hacked/unavailable:
├── ❌ Web interface doesn't work
├── ❌ Backend may show incorrect information
├── ❌ Frontend may be replaced
│
BUT:
├── ✅ All business assets remain on blockchain
├── ✅ Smart contracts continue to work
├── ✅ Tokens cannot be stolen
├── ✅ Can manage via Etherscan/Polygonscan/etc.
└── ✅ Can create new frontend and connect to same contracts
Real example:
- Attacker hacks your server with web application
- Tries to show fake token balances
- But: Real balances on blockchain remain unchanged
- You open Etherscan and see the truth
- Create proposal via Etherscan for recovery
- Vote and execute proposal
- Restore web application
- Result: Not a single token lost ✅
Token-Based Access Control
How It Works
Without tokens, access to application is IMPOSSIBLE.
Access attempt to DLE:
├── 1. User connects wallet
├── 2. Backend checks token balance in smart contract
├── 3. If NO tokens → Access DENIED
└── 4. If tokens EXIST → Access granted (level depends on amount)
Access Levels
| Tokens on balance | Access Level | Rights |
|---|---|---|
| 0 tokens | ❌ No access | Only "No access" page |
| 1+ tokens | ✅ ReadOnly | View data |
| 100+ tokens | ✅ Editor | Editing, creation |
| Any amount | 🗳️ Voting | 1 token = 1 vote |
Real-Time Token Verification
Backend constantly checks token balance:
// Every request checks tokens
async function checkAccess(req, res, next) {
const address = req.session.address;
// Get token balance from smart contract
const dleContract = new ethers.Contract(dleAddress, dleAbi, provider);
const balance = await dleContract.balanceOf(address);
if (balance === 0n) {
return res.status(403).json({
error: 'Access denied: no tokens'
});
}
// Determine access level
const accessLevel = determineAccessLevel(balance);
req.user = { address, balance, accessLevel };
next();
}
Important: Verification happens on every request, so:
- ✅ If tokens transferred → access instantly lost
- ✅ If tokens received → access instantly appears
- ✅ Impossible to bypass verification
Initial Token Distribution
Tokens are distributed by owner when deploying smart contract:
constructor(DLEConfig memory config) {
// Create tokens
_mint(address(this), totalSupply);
// Distribute among partners
for (uint i = 0; i < config.initialPartners.length; i++) {
_transfer(
address(this),
config.initialPartners[i],
config.initialAmounts[i]
);
}
}
Process:
- Wallet owner deploys DLE smart contract
- Specifies partner addresses and token amounts for each
- Tokens automatically distributed on deployment
- After that, all changes only through voting
Distribution example:
const config = {
initialPartners: [
'0xAlice...', // Founder 1
'0xBob...', // Founder 2
'0xCarol...' // Investor
],
initialAmounts: [
500000, // 50% for Alice
300000, // 30% for Bob
200000 // 20% for Carol
]
};
Smart Contract Security
Protection from Token Transfers
CRITICAL: Governance tokens CANNOT be transferred by normal means!
// Transfers BLOCKED
function transfer(address to, uint256 amount)
public
pure
override
returns (bool)
{
revert ErrTransfersDisabled();
}
// Approvals BLOCKED
function approve(address spender, uint256 amount)
public
pure
override
returns (bool)
{
revert ErrApprovalsDisabled();
}
// TransferFrom BLOCKED
function transferFrom(address from, address to, uint256 amount)
public
pure
override
returns (bool)
{
revert ErrTransfersDisabled();
}
What this means:
- ❌ Cannot send tokens to exchange
- ❌ Cannot sell tokens on DEX
- ❌ Cannot transfer tokens to another person directly
- ❌ Attacker CANNOT steal tokens even from hacked wallet
Only Way to Transfer Tokens
Only through voting with quorum:
// Transfer tokens (only through governance)
function _transferTokens(address recipient, uint256 amount) internal {
require(msg.sender == address(this), "Only through governance");
_transfer(address(this), recipient, amount);
}
Transfer process:
1. Proposal creation
├── "Transfer 1000 tokens to address 0xNew..."
└── Required: minimum 1 token to create
2. Voting
├── Duration: 1-30 days (configurable)
├── Each token = 1 vote
└── Required: quorum (e.g., 10% of all tokens)
3. Quorum check
├── If "For" > "Against" AND quorum reached
└── → Proposal approved
4. Execution
├── Smart contract automatically transfers tokens
└── Event recorded on blockchain forever
Quorum Configuration
Quorum is set on deployment and can only be changed through voting:
uint256 public quorumPercentage; // For example, 10%
function _hasQuorum(uint256 forVotes, uint256 againstVotes)
internal
view
returns (bool)
{
uint256 totalVotes = forVotes + againstVotes;
uint256 required = (totalSupply() * quorumPercentage) / 100;
return totalVotes >= required;
}
Quorum examples:
- 5% - easy to reach (for active organizations)
- 10% - standard (recommended)
- 20% - strict (for critical decisions)
- 51% - absolute majority
Reentrancy Protection
import "@openzeppelin/contracts/utils/ReentrancyGuard.sol";
contract DLE is ReentrancyGuard {
function execute(uint256 proposalId)
external
nonReentrant // Reentrancy protection
{
// Proposal execution
}
}
Flash-Loan Protection
Vote snapshots prevent attacks with temporary token loans:
// Votes taken from PREVIOUS block
uint256 public snapshotTimepoint = block.number - 1;
function vote(uint256 proposalId, bool support) external {
// Use balance from previous block
uint256 votingPower = getPastVotes(msg.sender, snapshotTimepoint);
require(votingPower > 0, "No voting power");
// Voting
}
Why this is safe:
- Attacker takes flash-loan of 1,000,000 tokens
- Tries to vote
- Smart contract checks balance in previous block
- In previous block attacker had 0 tokens
- Voting rejected ❌
Parameter Validation
// Address check
if (address == address(0)) revert ErrZeroAddress();
// Token ownership check
if (balanceOf(msg.sender) == 0) revert ErrNotHolder();
// Voting duration check
if (duration < minVotingDuration) revert ErrTooShort();
if (duration > maxVotingDuration) revert ErrTooLong();
// Supported network check
if (!supportedChains[chainId]) revert ErrUnsupportedChain();
Custom Errors for Gas Savings
// Gas savings: custom errors instead of require
error ErrZeroAddress();
error ErrNotHolder();
error ErrAlreadyVoted();
error ErrTransfersDisabled();
error ErrApprovalsDisabled();
error ErrProposalMissing();
error ErrWrongChain();
Wallet Hack Protection
Scenario: Attacker Got Private Key
What attacker can do:
Attacker attempts:
1. ❌ Send tokens to own address
└── BLOCKED: transfer() blocked
2. ❌ Sell tokens on DEX (Uniswap, etc.)
└── BLOCKED: approve() blocked
3. ❌ Send via transferFrom
└── BLOCKED: transferFrom() blocked
4. ❓ Create proposal "Transfer tokens to me"
└── Requires voting by other token holders
└── Quorum: 10%+ must vote "For"
└── MOST LIKELY WILL FAIL
Real Attack Example
Attacker hacked Alice's wallet (500,000 tokens):
1. Creates proposal:
"Transfer 500,000 tokens to address 0xEvil..."
2. Votes "For" with own 500,000 votes (50%)
3. But quorum = 10% = 100,000 votes
Already reached? YES ✅
4. "For" = 500,000 (50%)
"Against" = 0
5. Result: Proposal APPROVED ❌
PROBLEM: If Alice has majority of tokens!
Protection from Majority Token Attack
Solution 1: Timelock Module
// Delayed execution (e.g., 3 days)
uint256 public constant TIMELOCK_DELAY = 3 days;
function scheduleProposal(uint256 proposalId) external {
// Proposal approved, but executes only after 3 days
executionTime = block.timestamp + TIMELOCK_DELAY;
}
Advantage: Other token holders see dangerous proposal and can:
- Vote "Against"
- Create counter-proposal
- Take measures (e.g., contact court)
Solution 2: Multisignature
// Requires multiple signatures for critical operations
mapping(uint256 => mapping(address => bool)) public approvals;
function executeWithApprovals(
uint256 proposalId,
address[] calldata signers,
bytes[] calldata signatures
) external {
// Verify signatures of multiple token holders
require(signers.length >= minSigners, "Not enough signers");
for (uint i = 0; i < signers.length; i++) {
// Signature verification
verifySignature(proposalId, signers[i], signatures[i]);
}
// Execution
}
Solution 3: Cold Wallet for Large Holders
Recommended to keep tokens on:
- 🥶 Hardware wallet (Ledger, Trezor) - maximum protection
- 🔒 Multisignature (Gnosis Safe) - requires multiple signatures
- ❄️ Cold storage - offline, not connected to internet
Suspicious Proposal Monitoring
Backend automatically detects dangerous proposals:
// Suspicious proposal detector
function detectSuspiciousProposal(proposal) {
const alerts = [];
// Check 1: Transfer of large token amount
if (proposal.operation.includes('_transferTokens')) {
const amount = decodeAmount(proposal.operation);
const percentage = (amount / totalSupply) * 100;
if (percentage > 10) {
alerts.push({
level: 'HIGH',
message: `Proposal transfers ${percentage}% of all tokens!`
});
}
}
// Check 2: Initiator votes with own tokens
if (proposal.forVotes === proposal.initiatorBalance) {
alerts.push({
level: 'MEDIUM',
message: 'Initiator votes only with own tokens'
});
}
// Check 3: Fast voting (< 24 hours)
if (proposal.duration < 86400) {
alerts.push({
level: 'MEDIUM',
message: 'Voting less than 24 hours - little time for verification'
});
}
// Send notifications to all token holders
if (alerts.length > 0) {
notifyAllTokenHolders(proposal, alerts);
}
}
Web Application Security
SIWE Authentication
Sign-In with Ethereum - standard for secure authentication:
// Generate nonce (one-time)
const nonce = crypto.randomBytes(32).toString('hex');
// Save to DB with encryption
await db.query(
'INSERT INTO nonces (address_encrypted, nonce_encrypted, expires_at) VALUES ($1, $2, $3)',
[encrypt(address), encrypt(nonce), expiresAt]
);
// Signature verification
const message = new SiweMessage({
domain: req.get('host'),
address: ethers.getAddress(address),
nonce: nonce,
chainId: 1
});
const isValid = await verifySignature(
message.prepareMessage(),
signature,
address
);
Security:
- ✅ Private key never leaves wallet
- ✅ Each nonce used once
- ✅ Nonce expires in 5 minutes
- ✅ Impossible to forge signature without private key
Data Encryption
// AES-256 encryption
const crypto = require('crypto');
function encrypt(text, key) {
const iv = crypto.randomBytes(16);
const cipher = crypto.createCipheriv('aes-256-cbc', key, iv);
let encrypted = cipher.update(text, 'utf8', 'hex');
encrypted += cipher.final('hex');
return iv.toString('hex') + ':' + encrypted;
}
function decrypt(encrypted, key) {
const parts = encrypted.split(':');
const iv = Buffer.from(parts[0], 'hex');
const encryptedText = parts[1];
const decipher = crypto.createDecipheriv('aes-256-cbc', key, iv);
let decrypted = decipher.update(encryptedText, 'hex', 'utf8');
decrypted += decipher.final('utf8');
return decrypted;
}
What is encrypted:
- 🔐 Wallet addresses in DB
- 🔐 Nonces for authentication
- 🔐 Session data
- 🔐 Private messages
Rate Limiting
const rateLimit = require('express-rate-limit');
// Request limiting
const apiLimiter = rateLimit({
windowMs: 15 * 60 * 1000, // 15 minutes
max: 100, // maximum 100 requests
message: 'Too many requests, try again later'
});
// Authentication limiting (stricter)
const authLimiter = rateLimit({
windowMs: 15 * 60 * 1000,
max: 5, // maximum 5 authentication attempts
skipSuccessfulRequests: true
});
app.use('/api/', apiLimiter);
app.use('/api/auth/', authLimiter);
CSRF Protection
const csrf = require('csurf');
// CSRF tokens for all forms
const csrfProtection = csrf({ cookie: true });
app.post('/api/action', csrfProtection, async (req, res) => {
// CSRF token verification automatic
});
XSS Protection
import DOMPurify from 'dompurify';
// Clean HTML from dangerous code
function sanitizeHTML(html) {
return DOMPurify.sanitize(html, {
ALLOWED_TAGS: ['b', 'i', 'em', 'strong', 'a', 'p'],
ALLOWED_ATTR: ['href']
});
}
// Usage
const userInput = req.body.comment;
const safeHTML = sanitizeHTML(userInput);
Helmet.js for Header Protection
const helmet = require('helmet');
app.use(helmet({
contentSecurityPolicy: {
directives: {
defaultSrc: ["'self'"],
scriptSrc: ["'self'", "'unsafe-inline'"],
styleSrc: ["'self'", "'unsafe-inline'"],
imgSrc: ["'self'", "data:", "https:"],
}
},
hsts: {
maxAge: 31536000,
includeSubDomains: true,
preload: true
}
}));
Clean Logs System
Automatic log cleanup from sensitive data:
function cleanLogs() {
const sensitivePatterns = [
/0x[a-fA-F0-9]{40}/g, // Wallet addresses
/pk_[a-zA-Z0-9]{64}/g, // Private keys (if accidentally logged)
/nonce:\s*[a-f0-9]{64}/gi, // Nonces
];
// Replace sensitive data with ***
let cleanedLog = logContent;
sensitivePatterns.forEach(pattern => {
cleanedLog = cleanedLog.replace(pattern, '[REDACTED]');
});
return cleanedLog;
}
Module Management
Only DLE Smart Contract Manages Modules
onlyDLE modifier guarantees that only DLE smart contract can call module functions:
// Module: TreasuryModule
contract TreasuryModule {
address public immutable dleContract;
modifier onlyDLE() {
require(msg.sender == dleContract, "Only DLE can call");
_;
}
// Only DLE can transfer tokens from treasury
function transferTokens(
address token,
address recipient,
uint256 amount
) external onlyDLE {
IERC20(token).transfer(recipient, amount);
}
}
What this means:
- ❌ Wallet owner CANNOT directly call module functions
- ❌ Backend CANNOT call module functions
- ❌ Attacker CANNOT interact with module
- ✅ Only DLE smart contract through voting
Module Usage Process
1. Token holder creates proposal
└── "Transfer 1000 USDC from Treasury to marketing"
2. Proposal contains encoded module function call
└── operation = treasuryModule.transferTokens(USDC, marketing, 1000)
3. Voting
4. If approved, DLE contract calls module:
└── TreasuryModule.transferTokens() ✅
└── msg.sender = DLE contract ✅
5. Module verifies msg.sender and executes
Adding New Module
Only through voting:
// Module addition operation
function _addModule(bytes32 moduleId, address moduleAddress) internal {
require(msg.sender == address(this), "Only through voting");
require(moduleAddress != address(0), "Invalid address");
require(!activeModules[moduleId], "Module already exists");
modules[moduleId] = moduleAddress;
activeModules[moduleId] = true;
emit ModuleAdded(moduleId, moduleAddress);
}
Process:
- Deploy new module
- Create proposal: "Add module X at address 0x..."
- Voting
- If approved → module added
- Module can be used
Removing Compromised Module
If module turns out to be vulnerable:
1. Token holder creates emergency proposal
└── "Remove compromised module X"
└── Duration: 1 day (emergency voting)
2. Voting (accelerated)
3. Module removed
└── Can no longer be called from DLE contract
Audit and Monitoring
Blockchain Transparency
All actions recorded forever:
// Events for audit
event ProposalCreated(uint256 proposalId, address initiator);
event ProposalVoted(uint256 proposalId, address voter, bool support);
event ProposalExecuted(uint256 proposalId, bytes operation);
event ModuleAdded(bytes32 moduleId, address moduleAddress);
event TokensTransferred(address recipient, uint256 amount);
Verification in blockchain explorer:
https://etherscan.io/address/0xDLE_CONTRACT_ADDRESS
└── All transactions publicly visible
└── Impossible to hide or delete
Real-Time Monitoring
Backend tracks all events:
// Subscribe to smart contract events
dleContract.on('ProposalCreated', async (proposalId, initiator, event) => {
logger.info(`New proposal #${proposalId} from ${initiator}`);
// Get proposal details
const proposal = await dleContract.proposals(proposalId);
// Security analysis
const risks = analyzeProposalRisks(proposal);
// Notify token holders
if (risks.level === 'HIGH') {
await notifyAllTokenHolders({
type: 'SECURITY_ALERT',
proposalId,
risks
});
}
});
Alert System
// Critical events require immediate notification
const criticalEvents = [
'ProposalCreated', // New proposal
'ModuleAdded', // Module added
'TokensTransferred' // Tokens transferred
];
async function sendAlert(event, data) {
// Email notifications
await sendEmail({
to: allTokenHolders,
subject: `[DLE Alert] ${event}`,
body: formatAlert(data)
});
// Telegram notifications
await sendTelegram({
chat: dleNotificationsChat,
message: formatAlert(data)
});
// Log entry
logger.warn(`ALERT: ${event}`, data);
}
Security Recommendations
For Token Holders
-
🥶 Use hardware wallet (Ledger, Trezor)
- Private key never leaves device
- Confirmation of each operation on physical device
-
🔐 Store seed phrase securely
- Write on paper, don't store digitally
- Use metal plates for durability
- Store in safe or bank deposit box
-
🚨 Enable notifications
- Email alerts on new proposals
- Telegram bots for critical events
-
👀 Check all proposals
- Read description before voting
- Verify recipient addresses
- Use timelock for critical operations
-
❄️ Split tokens
- Hot wallet: 10-20% for daily use
- Cold wallet: 80-90% for long-term storage
For Administrators
-
🔄 Regular updates
# Weekly update docker-compose pull docker-compose up -d -
💾 Backups
# Daily database backup docker exec dapp-postgres pg_dump -U user db > backup.sql -
📊 Log monitoring
# Check logs for suspicious activity docker logs dapp-backend | grep -i "error\|warning\|failed" -
🔑 Encryption key rotation
- Change encryption key once a year
- Keep old keys for decrypting historical data
-
🛡️ Firewall configuration
# Allow only necessary ports ufw allow 80/tcp # HTTP ufw allow 443/tcp # HTTPS ufw enable
For Developers
-
✅ Smart contract audits
- Use Slither for static analysis
- Mythril for vulnerability search
- Manual audit of critical code
-
🧪 Testing
# Run tests cd backend yarn test # Code coverage yarn coverage -
📝 Code review
- All changes through pull requests
- Minimum 2 reviewers for critical changes
-
🔒 Secure dependencies
# Vulnerability check yarn audit npm audit fix
Attack Scenarios and Protection
Scenario 1: Phishing Attack
Attack:
1. Attacker creates fake site: dlle.com (instead of dle.com)
2. Sends phishing emails to token holders
3. Asks to connect wallet and sign transaction
Protection:
// Backend verifies domain in SIWE message
const message = new SiweMessage({
domain: req.get('host'), // Must be correct domain
uri: req.get('origin')
});
// Frontend shows warning
if (window.location.hostname !== 'dle.app') {
alert('⚠️ WARNING: This is NOT the official DLE site!');
}
User recommendations:
- ✅ Always verify URL before connecting wallet
- ✅ Use browser bookmarks
- ✅ Verify SSL certificate (green lock)
Scenario 2: Backend Server Hack
Attack:
1. Attacker gains access to backend server
2. Tries to modify code to bypass token verification
3. Or completely takes web application offline
Protection:
✅ Token verification happens on blockchain (immutable)
✅ Backend can be compromised, but:
├── Cannot change token balance in smart contract
├── Cannot create fake tokens
├── Cannot change smart contract rules
└── Users will see discrepancy between backend and blockchain
Critical: Web Application is Only an Interface!
Even with complete hack of web application:
- ✅ All business assets protected on blockchain
- ✅ Smart contracts continue to work independently of web application
- ✅ Can manage via blockchain explorers (Etherscan, Polygonscan, etc.)
Management via Blockchain Explorers
If web application unavailable, use blockchain explorers:
1. Check Token Balance
1. Open Etherscan: https://etherscan.io
2. Enter DLE smart contract address
3. Go to "Read Contract" tab
4. Call balanceOf(address) function
5. Enter your wallet address
6. Click "Query" - see token balance ✅
Example:
Contract Address: 0x1234...DLE
Function: balanceOf
Address: 0xYourWallet...
Result: 500000 (your token balance)
2. Create Proposal via Etherscan
1. Open Etherscan and find DLE smart contract
2. Go to "Write Contract" tab
3. Connect MetaMask wallet
4. Find createProposal function
5. Fill parameters:
- description: "Restore web application"
- operation: encoded function call
- votingDuration: 86400 (1 day in seconds)
6. Click "Write" and confirm transaction ✅
Example proposal creation:
// Via Etherscan Write Contract
createProposal(
"Transfer 10,000 USDT for infrastructure recovery",
0x..., // encoded transferTokens call
86400 // 1 day
)
3. Vote via Etherscan
1. Open DLE smart contract on Etherscan
2. "Write Contract" tab
3. Connect wallet
4. Function vote(uint256 proposalId, bool support)
- proposalId: proposal number (e.g., 5)
- support: true (for) or false (against)
5. Click "Write" ✅
4. Check Proposal Status
1. "Read Contract" tab on Etherscan
2. Function proposals(uint256)
3. Enter proposal ID
4. See all details:
- Description
- "For" and "Against" votes
- Status (Active, Executed, Failed)
- Voting end time
5. Execute Approved Proposal
1. If proposal approved and time expired
2. Open "Write Contract"
3. Function execute(uint256 proposalId)
4. Enter proposal ID
5. Click "Write" - proposal executes ✅
Popular Blockchain Explorers for DLE
| Network | Blockchain Explorer | URL |
|---|---|---|
| Ethereum Mainnet | Etherscan | https://etherscan.io |
| Polygon | Polygonscan | https://polygonscan.com |
| Binance Smart Chain | BscScan | https://bscscan.com |
| Arbitrum | Arbiscan | https://arbiscan.io |
| Optimism | Optimistic Etherscan | https://optimistic.etherscan.io |
| Avalanche | SnowTrace | https://snowtrace.io |
| Base | BaseScan | https://basescan.org |
Advantages of Management via Blockchain Explorers
1. Complete independence from web application
Web application hacked → Blockchain works ✅
Backend server down → Smart contracts work ✅
Frontend unavailable → Can manage via Etherscan ✅
2. Impossible to forge data
Attacker on backend → Blockchain explorer shows truth
Fake frontend → Etherscan shows real tokens
Modified logic → Smart contract works as intended
3. Access 24/7 from anywhere in the world
No server access → Etherscan always available
Application maintenance → Management via blockchain
DDoS attack on site → Blockchain unavailable for DDoS
Response to hack:
- Users notice strange web application behavior
- Check token balance directly via Etherscan ✅
- Create proposal via Etherscan for recovery
- Vote for infrastructure recovery
- Administrators restore backend from backup
- No tokens or assets lost ✅
Conclusion: Web application is just a convenient interface. Real power and assets are on blockchain, where they are protected by cryptography and impossible to change or steal through web application hack.
Scenario 3: 51% Attack
Attack:
1. Attacker buys or gets >51% of all tokens
2. Creates proposal "Transfer all assets to me"
3. Votes with all own tokens "For"
4. Proposal approved
Protection:
// Timelock Module gives time to react
const TIMELOCK = 7 days;
// Other token holders can:
1. Vote "Against" (if they still have 49%)
2. Create counter-proposal
3. Contact law enforcement
4. Cancel proposal via emergency function (if configured)
Long-term protection:
- Even token distribution among partners
- Multisignature for large operations
- Quadratic voting (option for future versions)
Scenario 4: Social Engineering
Attack:
1. Attacker impersonates DLE support
2. Asks token holder "for verification" to sign message
3. Message is actually approval to transfer tokens
Protection:
// Frontend always shows WHAT is being signed
function signMessage(message) {
// Show user exact content
const confirmation = confirm(`
You are about to sign:
${message}
⚠️ NEVER sign messages at request of "support"!
Continue?
`);
if (!confirmation) return;
// Sign
}
Recommendations:
- ❌ Support NEVER asks to sign message
- ❌ Don't trust "urgent" requests
- ✅ Always verify what you're signing
- ✅ If in doubt - contact official support
Conclusion
Multi-Layer DLE Protection
┌─────────────────────────────────────────────────────┐
│ DLE Security Levels │
├─────────────────────────────────────────────────────┤
│ 1️⃣ Blockchain │
│ └── Tokens cannot be stolen even with hack │
│ │
│ 2️⃣ Smart Contracts │
│ └── Audit, OpenZeppelin, immutability │
│ │
│ 3️⃣ Voting with quorum │
│ └── Impossible to make unilateral decisions │
│ │
│ 4️⃣ Timelock │
│ └── Time to react in case of attack │
│ │
│ 5️⃣ Backend verification │
│ └── Real-time token verification │
│ │
│ 6️⃣ Frontend protection │
│ └── XSS, CSRF, rate limiting │
│ │
│ 7️⃣ Monitoring and alerts │
│ └── Detection of suspicious actions │
└─────────────────────────────────────────────────────┘
Key Security Advantages
-
🔐 Token-based access control
- Without tokens access impossible
- Real-time verification on blockchain
-
🛡️ Protection from token theft
- Cannot transfer without voting
- Even if wallet hacked, tokens protected
-
🌐 Independence from web application
- Even if web application hacked, business assets protected on blockchain
- Can manage via blockchain explorers (Etherscan, Polygonscan, etc.)
- Smart contracts work independently of frontend/backend
- Web application is only convenient interface, real power on blockchain
-
⚖️ Collective governance
- Critical decisions only through voting
- Quorum prevents unilateral actions
-
🔒 Modules under smart contract control
- Only DLE contract can call modules
- No direct access
-
📊 Full transparency
- All actions on blockchain
- Impossible to hide or forge
Next Steps
© 2024-2025 Tarabanov Alexander Viktorovich. All rights reserved.
Last update: October 2025